summaryrefslogtreecommitdiffstats
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/font/LogicalFontInstance.hxx3
-rw-r--r--vcl/inc/impfontcache.hxx8
-rw-r--r--vcl/inc/impglyphitem.hxx6
-rw-r--r--vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx12
-rw-r--r--vcl/qa/cppunit/logicalfontinstance.cxx68
-rw-r--r--vcl/qa/cppunit/pdfexport/data/tdf142133.docxbin0 -> 12078 bytes
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport.cxx35
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport2.cxx6
-rw-r--r--vcl/quartz/cgutils.mm10
-rw-r--r--vcl/skia/gdiimpl.cxx20
-rw-r--r--vcl/skia/osx/gdiimpl.cxx21
-rw-r--r--vcl/source/app/salvtables.cxx2
-rw-r--r--vcl/source/app/svmain.cxx2
-rw-r--r--vcl/source/bitmap/BitmapEx.cxx11
-rw-r--r--vcl/source/control/scrbar.cxx6
-rw-r--r--vcl/source/filter/webp/reader.cxx4
-rw-r--r--vcl/source/font/LogicalFontInstance.cxx53
-rw-r--r--vcl/source/font/fontcache.cxx4
-rw-r--r--vcl/source/gdi/CommonSalLayout.cxx6
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx18
-rw-r--r--vcl/source/gdi/sallayout.cxx44
-rw-r--r--vcl/source/outdev/font.cxx4
-rw-r--r--vcl/source/treelist/iconviewimpl.cxx1
-rw-r--r--vcl/source/window/accessibility.cxx2
-rw-r--r--vcl/source/window/legacyaccessibility.cxx2
-rw-r--r--vcl/source/window/printdlg.cxx2
-rw-r--r--vcl/unx/gtk3/gtkframe.cxx22
-rw-r--r--vcl/unx/gtk3/gtkinst.cxx38
-rw-r--r--vcl/win/window/salframe.cxx2
-rw-r--r--vcl/workben/listglyphs.cxx2
30 files changed, 301 insertions, 113 deletions
diff --git a/vcl/inc/font/LogicalFontInstance.hxx b/vcl/inc/font/LogicalFontInstance.hxx
index 40d3c57c4e..73ba2e26a2 100644
--- a/vcl/inc/font/LogicalFontInstance.hxx
+++ b/vcl/inc/font/LogicalFontInstance.hxx
@@ -22,6 +22,7 @@
#include <sal/config.h>
#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/range/b2drectangle.hxx>
#include <o3tl/hash_combine.hxx>
#include <rtl/ref.hxx>
#include <salhelper/simplereferenceobject.hxx>
@@ -100,7 +101,7 @@ public: // TODO: make data members private
vcl::font::PhysicalFontFace* GetFontFace() { return m_pFontFace.get(); }
const ImplFontCache* GetFontCache() const { return mpFontCache; }
- bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const;
+ bool GetGlyphBoundRect(sal_GlyphId, basegfx::B2DRectangle&, bool) const;
virtual bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const = 0;
basegfx::B2DPolyPolygon GetGlyphOutlineUntransformed(sal_GlyphId) const;
diff --git a/vcl/inc/impfontcache.hxx b/vcl/inc/impfontcache.hxx
index 5ea19b05d9..4d197003b2 100644
--- a/vcl/inc/impfontcache.hxx
+++ b/vcl/inc/impfontcache.hxx
@@ -21,10 +21,10 @@
#include <sal/config.h>
+#include <basegfx/range/b2drectangle.hxx>
#include <rtl/ref.hxx>
#include <o3tl/lru_map.hxx>
#include <o3tl/hash_combine.hxx>
-#include <tools/gen.hxx>
#include "font/FontSelectPattern.hxx"
#include "glyphid.hxx"
@@ -59,7 +59,7 @@ struct GlyphBoundRectCacheHash
}
};
-typedef o3tl::lru_map<GlyphBoundRectCacheKey, tools::Rectangle,
+typedef o3tl::lru_map<GlyphBoundRectCacheKey, basegfx::B2DRectangle,
GlyphBoundRectCacheHash> GlyphBoundRectCache;
class ImplFontCache
@@ -86,8 +86,8 @@ public:
LogicalFontInstance* pLogicalFont,
int nFallbackLevel, OUString& rMissingCodes );
- bool GetCachedGlyphBoundRect(const LogicalFontInstance *, sal_GlyphId, tools::Rectangle &);
- void CacheGlyphBoundRect(const LogicalFontInstance *, sal_GlyphId, tools::Rectangle &);
+ bool GetCachedGlyphBoundRect(const LogicalFontInstance*, sal_GlyphId, basegfx::B2DRectangle&);
+ void CacheGlyphBoundRect(const LogicalFontInstance*, sal_GlyphId, basegfx::B2DRectangle&);
void Invalidate();
};
diff --git a/vcl/inc/impglyphitem.hxx b/vcl/inc/impglyphitem.hxx
index 1fa8454e2e..bb08031f3a 100644
--- a/vcl/inc/impglyphitem.hxx
+++ b/vcl/inc/impglyphitem.hxx
@@ -20,8 +20,8 @@
#ifndef INCLUDED_VCL_IMPGLYPHITEM_HXX
#define INCLUDED_VCL_IMPGLYPHITEM_HXX
+#include <basegfx/range/b2drectangle.hxx>
#include <o3tl/typed_flags_set.hxx>
-#include <tools/gen.hxx>
#include <vcl/dllapi.h>
#include <vcl/rendercontext/SalLayoutFlags.hxx>
#include <rtl/math.hxx>
@@ -89,7 +89,7 @@ public:
return bool(m_nFlags & GlyphItemFlags::IS_SAFE_TO_INSERT_KASHIDA);
}
- inline bool GetGlyphBoundRect(const LogicalFontInstance*, tools::Rectangle&) const;
+ inline bool GetGlyphBoundRect(const LogicalFontInstance*, basegfx::B2DRectangle&) const;
inline bool GetGlyphOutline(const LogicalFontInstance*, basegfx::B2DPolyPolygon&) const;
inline void dropGlyph();
@@ -121,7 +121,7 @@ public:
};
bool GlyphItem::GetGlyphBoundRect(const LogicalFontInstance* pFontInstance,
- tools::Rectangle& rRect) const
+ basegfx::B2DRectangle& rRect) const
{
return pFontInstance->GetGlyphBoundRect(m_aGlyphId, rRect, IsVertical());
}
diff --git a/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx b/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx
index d3c43f4819..cbc23315ca 100644
--- a/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx
+++ b/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx
@@ -141,10 +141,10 @@ void WebpFilterTest::testRoundtrip(bool lossy)
}
AlphaMask tmpAlpha = aResultBitmap.GetAlphaMask();
BitmapScopedReadAccess pAccessAlpha(tmpAlpha);
- CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), pAccessAlpha->GetPixelIndex(0, 0));
- CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), pAccessAlpha->GetPixelIndex(0, 19));
- CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), pAccessAlpha->GetPixelIndex(19, 0));
- CPPUNIT_ASSERT_EQUAL(sal_uInt8(64), pAccessAlpha->GetPixelIndex(19, 19));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), pAccessAlpha->GetPixelIndex(0, 0));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), pAccessAlpha->GetPixelIndex(0, 19));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), pAccessAlpha->GetPixelIndex(19, 0));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt8(191), pAccessAlpha->GetPixelIndex(19, 19));
}
aStream.Seek(STREAM_SEEK_TO_BEGIN);
@@ -192,8 +192,8 @@ void WebpFilterTest::testRead(std::u16string_view rName, bool lossy, bool alpha)
{
AlphaMask tmpAlpha = aResultBitmap.GetAlphaMask();
BitmapScopedReadAccess pAccessAlpha(tmpAlpha);
- CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), pAccessAlpha->GetPixelIndex(0, 0));
- CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), pAccessAlpha->GetPixelIndex(0, 9));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), pAccessAlpha->GetPixelIndex(0, 0));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), pAccessAlpha->GetPixelIndex(0, 9));
}
}
}
diff --git a/vcl/qa/cppunit/logicalfontinstance.cxx b/vcl/qa/cppunit/logicalfontinstance.cxx
index 6d5bbc4daf..eb803ed403 100644
--- a/vcl/qa/cppunit/logicalfontinstance.cxx
+++ b/vcl/qa/cppunit/logicalfontinstance.cxx
@@ -39,25 +39,71 @@ void VclLogicalFontInstanceTest::testglyphboundrect()
{
ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA);
device->SetOutputSizePixel(Size(1000, 1000));
- device->SetFont(vcl::Font("Liberation Sans", Size(0, 110)));
+ vcl::Font font("Liberation Sans", Size(0, 110));
+ device->SetFont(font);
const LogicalFontInstance* pFontInstance = device->GetFontInstance();
- tools::Rectangle aBoundRect;
+ basegfx::B2DRectangle aBoundRect;
const auto LATIN_SMALL_LETTER_B = 0x0062;
+ const auto SECTION_SIGN = 0x00A7; // UTR#50: Vertical_Orientation (vo) property value U
pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(LATIN_SMALL_LETTER_B), aBoundRect,
false);
- const tools::Long nExpectedX = 7;
- const tools::Long nExpectedY = -80;
- const tools::Long nExpectedWidth = 51;
- const tools::Long nExpectedHeight = 83;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(7.1, aBoundRect.getMinX(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-79.7, aBoundRect.getMinY(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(49.5, aBoundRect.getWidth(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(80.8, aBoundRect.getHeight(), 0.05);
- CPPUNIT_ASSERT_EQUAL_MESSAGE("x of glyph is wrong", nExpectedX, aBoundRect.getX());
- CPPUNIT_ASSERT_EQUAL_MESSAGE("y of glyph is wrong", nExpectedY, aBoundRect.getY());
- CPPUNIT_ASSERT_EQUAL_MESSAGE("height of glyph of wrong", nExpectedWidth, aBoundRect.GetWidth());
- CPPUNIT_ASSERT_EQUAL_MESSAGE("width of glyph of wrong", nExpectedHeight,
- aBoundRect.GetHeight());
+ // tdf#160436: test vertically oriented glyphs
+ pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(SECTION_SIGN), aBoundRect, true);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-79.7, aBoundRect.getMinX(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-55.0, aBoundRect.getMinY(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(88.9, aBoundRect.getWidth(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(48.8, aBoundRect.getHeight(), 0.05);
+
+ font.SetOrientation(900_deg10);
+ device->SetFont(font);
+
+ pFontInstance = device->GetFontInstance();
+
+ pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(LATIN_SMALL_LETTER_B), aBoundRect,
+ false);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-79.7, aBoundRect.getMinX(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-56.6, aBoundRect.getMinY(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(80.8, aBoundRect.getWidth(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(49.5, aBoundRect.getHeight(), 0.05);
+
+ // tdf#160436: test vertically oriented glyphs
+ pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(SECTION_SIGN), aBoundRect, true);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-55.0, aBoundRect.getMinX(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-9.2, aBoundRect.getMinY(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(48.8, aBoundRect.getWidth(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(88.9, aBoundRect.getHeight(), 0.05);
+
+ font.SetOrientation(450_deg10);
+ device->SetFont(font);
+
+ pFontInstance = device->GetFontInstance();
+
+ pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(LATIN_SMALL_LETTER_B), aBoundRect,
+ false);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-51.3, aBoundRect.getMinX(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-96.4, aBoundRect.getMinY(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(92.1, aBoundRect.getWidth(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(92.1, aBoundRect.getHeight(), 0.05);
+
+ // tdf#160436: test vertically oriented glyphs
+ pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(SECTION_SIGN), aBoundRect, true);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-95.3, aBoundRect.getMinX(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-45.4, aBoundRect.getMinY(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(97.4, aBoundRect.getWidth(), 0.05);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(97.4, aBoundRect.getHeight(), 0.05);
}
CPPUNIT_TEST_SUITE_REGISTRATION(VclLogicalFontInstanceTest);
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf142133.docx b/vcl/qa/cppunit/pdfexport/data/tdf142133.docx
new file mode 100644
index 0000000000..fa1e155b87
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/tdf142133.docx
Binary files differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index d362a38553..e9a8530c3c 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -2740,6 +2740,41 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf157816Link)
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), pAnnots->GetElements().size());
}
+CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf142133)
+{
+ vcl::filter::PDFDocument aDocument;
+ load(u"tdf142133.docx", aDocument);
+
+ // The document has one page.
+ std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+
+ auto pAnnots = dynamic_cast<vcl::filter::PDFArrayElement*>(aPages[0]->Lookup("Annots"_ostr));
+ CPPUNIT_ASSERT(pAnnots);
+
+ // There should be one annotation
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pAnnots->GetElements().size());
+ auto pAnnotReference
+ = dynamic_cast<vcl::filter::PDFReferenceElement*>(pAnnots->GetElements()[0]);
+ CPPUNIT_ASSERT(pAnnotReference);
+ vcl::filter::PDFObjectElement* pAnnot = pAnnotReference->LookupObject();
+ CPPUNIT_ASSERT(pAnnot);
+ // We're expecting something like /Type /Annot /A << /Type /Action /S /URI /URI (path)
+ CPPUNIT_ASSERT_EQUAL(
+ "Annot"_ostr,
+ static_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Type"_ostr))->GetValue());
+ CPPUNIT_ASSERT_EQUAL(
+ "Link"_ostr,
+ static_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Subtype"_ostr))->GetValue());
+ auto pAction = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pAnnot->Lookup("A"_ostr));
+ CPPUNIT_ASSERT(pAction);
+ auto pURIElem
+ = dynamic_cast<vcl::filter::PDFLiteralStringElement*>(pAction->LookupElement("URI"_ostr));
+ CPPUNIT_ASSERT(pURIElem);
+ // Check it matches
+ CPPUNIT_ASSERT_EQUAL("https://google.com/"_ostr, pURIElem->GetValue());
+}
+
CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf142806)
{
aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
index 38e3629497..a464798076 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
@@ -40,6 +40,7 @@
#include <o3tl/string_view.hxx>
#include <vcl/filter/PDFiumLibrary.hxx>
+#include <vcl/pdfread.hxx>
#include <comphelper/propertyvalue.hxx>
#include <cmath>
@@ -4580,7 +4581,10 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testRexportMediaBoxOrigin)
= { // Rotation by $\theta$ $cos(\theta), sin(\theta), -sin(\theta), cos(\theta)$
0, -1, 1, 0,
// Translate x,y
- -aOrigin[1] - aSize[1] / 2 + aSize[0] / 2, aOrigin[0] + aSize[0] / 2 + aSize[1] / 2
+ -aOrigin[1] - aSize[1] / vcl::PDF_INSERT_MAGIC_SCALE_FACTOR / 2
+ + aSize[0] / vcl::PDF_INSERT_MAGIC_SCALE_FACTOR / 2,
+ aOrigin[0] + aSize[0] / vcl::PDF_INSERT_MAGIC_SCALE_FACTOR / 2
+ + aSize[1] / vcl::PDF_INSERT_MAGIC_SCALE_FACTOR / 2
};
for (sal_Int32 nIdx = 0; nIdx < 6; ++nIdx)
diff --git a/vcl/quartz/cgutils.mm b/vcl/quartz/cgutils.mm
index 0d611bec11..50b7fcd654 100644
--- a/vcl/quartz/cgutils.mm
+++ b/vcl/quartz/cgutils.mm
@@ -122,6 +122,16 @@ bool DefaultMTLDeviceIsSupported()
bRet = false;
}
+ if (bRet)
+ {
+ // tdf#160590 Disable Metal with Intel HD Graphics 6000
+ // Releasing a Metal buffer resource hangs when fetching pixels from a
+ // Skia surface on this Intel MacBook Air built-in GPU.
+ static NSString* pIntelHDGraphics6000Prefix = @"Intel(R) Iris(TM) Graphics 6000";
+ if ([pMetalDevice.name hasPrefix:pIntelHDGraphics6000Prefix])
+ bRet = false;
+ }
+
[pMetalDevice release];
return bRet;
}
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index d7028b9598..dce3175feb 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -1490,6 +1490,26 @@ void SkiaSalGraphicsImpl::invert(basegfx::B2DPolygon const& rPoly, SalInvert eFl
aPaint.setShader(
aBitmap.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions()));
}
+
+#ifdef SK_METAL
+ // tdf#153306 prevent subpixel shifting of X coordinate
+ // HACK: for some unknown reason, if the X coordinate of the
+ // path's bounds is more than 1024, SkBlendMode::kExclusion will
+ // shift by about a half a pixel to the right with Skia/Metal on
+ // a Retina display. Weirdly, if the same polygon is repeatedly
+ // drawn, the total shift is cumulative so if the drawn polygon
+ // is more than a few pixels wide, the blinking cursor in Writer
+ // will exhibit this bug but only for one thin vertical slice at
+ // a time. Apparently, shifting drawing a very tiny amount to
+ // the left seems to be enough to quell this runaway cumulative
+ // X coordinate shift.
+ if (isGPU())
+ {
+ SkMatrix aMatrix;
+ aMatrix.set(SkMatrix::kMTransX, -0.001);
+ getDrawCanvas()->concat(aMatrix);
+ }
+#endif
}
getDrawCanvas()->drawPath(aPath, aPaint);
postDraw();
diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx
index c4bd751842..9b511ad446 100644
--- a/vcl/skia/osx/gdiimpl.cxx
+++ b/vcl/skia/osx/gdiimpl.cxx
@@ -37,12 +37,6 @@
using namespace SkiaHelper;
-static void releaseInstalledPixels(void* pAddr, void*)
-{
- if (pAddr)
- delete[] static_cast<sal_uInt8*>(pAddr);
-}
-
AquaSkiaSalGraphicsImpl::AquaSkiaSalGraphicsImpl(AquaSalGraphics& rParent,
AquaSharedAttributes& rShared)
: SkiaSalGraphicsImpl(rParent, rShared.mpFrame)
@@ -251,6 +245,7 @@ bool AquaSkiaSalGraphicsImpl::drawNativeControl(ControlType nType, ControlPart n
if (!context)
{
SAL_WARN("vcl.skia", "drawNativeControl(): Failed to allocate bitmap context");
+ delete[] data;
return false;
}
// Setup context state for drawing (performDrawNativeControl() e.g. fills background in some cases).
@@ -287,12 +282,9 @@ bool AquaSkiaSalGraphicsImpl::drawNativeControl(ControlType nType, ControlPart n
if (!bitmap.installPixels(SkImageInfo::Make(width, height,
mSurface->imageInfo().colorType(),
kPremul_SkAlphaType),
- data, width * 4, releaseInstalledPixels, nullptr))
+ data, width * 4, nullptr, nullptr))
abort();
- // Make bitmap immutable to avoid making a copy in bitmap.asImage()
- bitmap.setImmutable();
-
preDraw();
SAL_INFO("vcl.skia.trace", "drawnativecontrol(" << this << "): " << rControlRegion << ":"
<< int(nType) << "/" << int(nPart));
@@ -312,6 +304,15 @@ bool AquaSkiaSalGraphicsImpl::drawNativeControl(ControlType nType, ControlPart n
++pendingOperationsToFlush; // tdf#136369
postDraw();
}
+ // Related: tdf#159529 eliminate possible memory leak
+ // Despite confirming that the release function passed to
+ // SkBitmap.bitmap.installPixels() does get called for every
+ // data array that has been allocated, Apple's Instruments
+ // indicates that the data is leaking. While it is likely a
+ // false positive, it makes leak analysis difficult so leave
+ // the bitmap mutable. That causes SkBitmap.asImage() to make
+ // a copy of the data and the data can be safely deleted here.
+ delete[] data;
return bOK;
}
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 50ecd194bd..faf645fc79 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -2592,6 +2592,8 @@ public:
else
m_xScrollBar->set_width_request(nThickness);
}
+
+ virtual void set_scroll_swap_arrows(bool bSwap) override { m_xScrollBar->SetSwapArrows(bSwap); }
};
}
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index 3aa2cecf4e..9eb99f09e3 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -194,7 +194,7 @@ int ImplSVMain()
const bool bWasInitVCL = IsVCLInit();
-#if defined(LINUX) && !defined(SYSTEM_OPENSSL)
+#if !defined(_WIN32) && !defined(SYSTEM_OPENSSL)
if (!bWasInitVCL)
{
OUString constexpr name(u"SSL_CERT_FILE"_ustr);
diff --git a/vcl/source/bitmap/BitmapEx.cxx b/vcl/source/bitmap/BitmapEx.cxx
index 40feacbf66..07e25f1771 100644
--- a/vcl/source/bitmap/BitmapEx.cxx
+++ b/vcl/source/bitmap/BitmapEx.cxx
@@ -657,7 +657,7 @@ namespace
const Bitmap& rSource,
const Size& rDestinationSize,
const basegfx::B2DHomMatrix& rTransform,
- bool bSmooth)
+ bool bSmooth, bool bAlphaMask)
{
Bitmap aDestination(rDestinationSize, vcl::PixelFormat::N24_BPP);
BitmapScopedWriteAccess xWrite(aDestination);
@@ -673,7 +673,10 @@ namespace
// tdf#157795 set color to black outside of bitmap bounds
// Due to commit 81994cb2b8b32453a92bcb011830fcb884f22ff3,
// transparent areas are now black instead of white.
- const BitmapColor aOutside(0x0, 0x0, 0x0);
+ // tdf#160831 only set outside color to black for alpha masks
+ // The outside color still needs to be white for the content
+ // so only apply the fix for tdf#157795 to the alpha mask.
+ const BitmapColor aOutside = bAlphaMask ? BitmapColor(0x0, 0x0, 0x0) : BitmapColor(0xff, 0xff, 0xff);
for(tools::Long y(0); y < aDestinationSizePixel.getHeight(); y++)
{
@@ -759,12 +762,12 @@ BitmapEx BitmapEx::TransformBitmapEx(
// force destination to 24 bit, we want to smooth output
const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight));
bool bSmooth = implTransformNeedsSmooth(rTransformation);
- const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth));
+ const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth, false));
// create mask
if(IsAlpha())
{
- const Bitmap aAlpha(impTransformBitmap(GetAlphaMask().GetBitmap(), aDestinationSize, rTransformation, bSmooth));
+ const Bitmap aAlpha(impTransformBitmap(GetAlphaMask().GetBitmap(), aDestinationSize, rTransformation, bSmooth, true));
return BitmapEx(aDestination, AlphaMask(aAlpha));
}
diff --git a/vcl/source/control/scrbar.cxx b/vcl/source/control/scrbar.cxx
index b652360139..7218b1485b 100644
--- a/vcl/source/control/scrbar.cxx
+++ b/vcl/source/control/scrbar.cxx
@@ -85,6 +85,7 @@ void ScrollBar::ImplInit( vcl::Window* pParent, WinBits nStyle )
meScrollType = ScrollType::DontKnow;
mbCalcSize = true;
mbFullDrag = false;
+ mbSwapArrows = false;
ImplInitStyle( nStyle );
Control::ImplInit( pParent, nStyle, nullptr );
@@ -240,6 +241,7 @@ void ScrollBar::ImplCalc( bool bUpdate )
const tools::Rectangle aControlRegion( Point(0,0), aSize );
tools::Rectangle aBtn1Region, aBtn2Region, aTrackRegion, aBoundingRegion;
+ const bool bSwapArrows = mbSwapArrows || IsRTLEnabled();
// reset rectangles to empty *and* (0,0) position
maThumbRect = tools::Rectangle();
@@ -248,9 +250,9 @@ void ScrollBar::ImplCalc( bool bUpdate )
if ( GetStyle() & WB_HORZ )
{
- if ( GetNativeControlRegion( ControlType::Scrollbar, IsRTLEnabled()? ControlPart::ButtonRight: ControlPart::ButtonLeft,
+ if ( GetNativeControlRegion( ControlType::Scrollbar, bSwapArrows? ControlPart::ButtonRight: ControlPart::ButtonLeft,
aControlRegion, ControlState::NONE, ImplControlValue(), aBoundingRegion, aBtn1Region ) &&
- GetNativeControlRegion( ControlType::Scrollbar, IsRTLEnabled()? ControlPart::ButtonLeft: ControlPart::ButtonRight,
+ GetNativeControlRegion( ControlType::Scrollbar, bSwapArrows? ControlPart::ButtonLeft: ControlPart::ButtonRight,
aControlRegion, ControlState::NONE, ImplControlValue(), aBoundingRegion, aBtn2Region ) )
{
maBtn1Rect = aBtn1Region;
diff --git a/vcl/source/filter/webp/reader.cxx b/vcl/source/filter/webp/reader.cxx
index 1d75ff79e8..2003312476 100644
--- a/vcl/source/filter/webp/reader.cxx
+++ b/vcl/source/filter/webp/reader.cxx
@@ -241,7 +241,7 @@ static bool readWebp(SvStream& stream, Graphic& graphic)
for (tools::Long x = 0; x < access->Width(); ++x)
{
memcpy(dstB, src, 3);
- *dstA = 255 - *(src + 3);
+ *dstA = *(src + 3);
src += 4;
dstB += 3;
dstA += 1;
@@ -273,7 +273,7 @@ static bool readWebp(SvStream& stream, Graphic& graphic)
for (tools::Long x = 0; x < accessAlpha->Width(); ++x)
{
sal_uInt8 a = src[3];
- accessAlpha->SetPixelIndex(y, x, 255 - a);
+ accessAlpha->SetPixelIndex(y, x, a);
src += 4;
}
}
diff --git a/vcl/source/font/LogicalFontInstance.cxx b/vcl/source/font/LogicalFontInstance.cxx
index 0c21cba475..3cf95cab8d 100644
--- a/vcl/source/font/LogicalFontInstance.cxx
+++ b/vcl/source/font/LogicalFontInstance.cxx
@@ -26,6 +26,8 @@
#include <font/LogicalFontInstance.hxx>
#include <impfontcache.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
LogicalFontInstance::LogicalFontInstance(const vcl::font::PhysicalFontFace& rFontFace,
const vcl::font::FontSelectPattern& rFontSelData)
: mxFontMetric(new FontMetricData(rFontSelData))
@@ -166,47 +168,42 @@ void LogicalFontInstance::IgnoreFallbackForUnicode(sal_UCS4 cChar, FontWeight eW
maUnicodeFallbackList.erase(it);
}
-bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle& rRect,
+bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, basegfx::B2DRectangle& rRect,
bool bVertical) const
{
+ // TODO: find out if it's possible for the same glyph in the same font to be used both
+ // normally and vertically; if yes, then these two variants must be cached separately
+
if (mpFontCache && mpFontCache->GetCachedGlyphBoundRect(this, nID, rRect))
return true;
auto* pHbFont = const_cast<LogicalFontInstance*>(this)->GetHbFont();
hb_glyph_extents_t aExtents;
- bool res = hb_font_get_glyph_extents(pHbFont, nID, &aExtents);
+ if (!hb_font_get_glyph_extents(pHbFont, nID, &aExtents))
+ return false;
- if (res)
- {
- double nXScale = 0, nYScale = 0;
- GetScale(&nXScale, &nYScale);
+ double nXScale = 0, nYScale = 0;
+ GetScale(&nXScale, &nYScale);
- double fMinX = aExtents.x_bearing;
- double fMinY = aExtents.y_bearing;
- double fMaxX = aExtents.x_bearing + aExtents.width;
- double fMaxY = aExtents.y_bearing + aExtents.height;
+ double fMinX = aExtents.x_bearing * nXScale;
+ double fMinY = -aExtents.y_bearing * nYScale;
+ double fMaxX = (aExtents.x_bearing + aExtents.width) * nXScale;
+ double fMaxY = -(aExtents.y_bearing + aExtents.height) * nYScale;
+ rRect = basegfx::B2DRectangle(fMinX, fMinY, fMaxX, fMaxY);
- tools::Rectangle aRect(std::floor(fMinX * nXScale), -std::ceil(fMinY * nYScale),
- std::ceil(fMaxX * nXScale), -std::floor(fMaxY * nYScale));
- if (mnOrientation && !bVertical)
- {
- // Apply font rotation.
- const double fRad = toRadians(mnOrientation);
- const double fCos = cos(fRad);
- const double fSin = sin(fRad);
-
- rRect.SetLeft(fCos * aRect.Left() + fSin * aRect.Top());
- rRect.SetTop(-fSin * aRect.Left() - fCos * aRect.Top());
- rRect.SetRight(fCos * aRect.Right() + fSin * aRect.Bottom());
- rRect.SetBottom(-fSin * aRect.Right() - fCos * aRect.Bottom());
- }
- else
- rRect = aRect;
+ auto orientation = mnOrientation;
+ if (bVertical)
+ orientation += 900_deg10;
+ if (orientation)
+ {
+ // Apply font rotation.
+ rRect.transform(basegfx::utils::createRotateB2DHomMatrix(-toRadians(orientation)));
}
- if (mpFontCache && res)
+ if (mpFontCache)
mpFontCache->CacheGlyphBoundRect(this, nID, rRect);
- return res;
+
+ return true;
}
sal_GlyphId LogicalFontInstance::GetGlyphIndex(uint32_t nUnicode, uint32_t nVariationSelector) const
diff --git a/vcl/source/font/fontcache.cxx b/vcl/source/font/fontcache.cxx
index c0dba15350..ce4ba6adf6 100644
--- a/vcl/source/font/fontcache.cxx
+++ b/vcl/source/font/fontcache.cxx
@@ -252,7 +252,7 @@ void ImplFontCache::Invalidate()
m_aBoundRectCache.clear();
}
-bool ImplFontCache::GetCachedGlyphBoundRect(const LogicalFontInstance *pFont, sal_GlyphId nID, tools::Rectangle &rRect)
+bool ImplFontCache::GetCachedGlyphBoundRect(const LogicalFontInstance *pFont, sal_GlyphId nID, basegfx::B2DRectangle &rRect)
{
if (!pFont->GetFontCache())
return false;
@@ -269,7 +269,7 @@ bool ImplFontCache::GetCachedGlyphBoundRect(const LogicalFontInstance *pFont, sa
return false;
}
-void ImplFontCache::CacheGlyphBoundRect(const LogicalFontInstance *pFont, sal_GlyphId nID, tools::Rectangle &rRect)
+void ImplFontCache::CacheGlyphBoundRect(const LogicalFontInstance *pFont, sal_GlyphId nID, basegfx::B2DRectangle &rRect)
{
if (!pFont->GetFontCache())
return;
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index bcf6f54639..455428e7f3 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -534,12 +534,12 @@ bool GenericSalLayout::LayoutText(vcl::text::ImplLayoutArgs& rArgs, const SalLay
{
// We need glyph's advance, top bearing, and height to
// correct y offset.
- tools::Rectangle aRect;
+ basegfx::B2DRectangle aRect;
// Get cached bound rect value for the font,
GetFont().GetGlyphBoundRect(nGlyphIndex, aRect, true);
- nXOffset = -(aRect.Top() / nXScale + ( pHbPositions[i].y_advance
- + ( aRect.GetHeight() / nXScale ) ) / 2.0 );
+ nXOffset = -(aRect.getMinX() / nXScale + ( pHbPositions[i].y_advance
+ + ( aRect.getHeight() / nXScale ) ) / 2.0 );
}
}
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index a5365e681b..ff7383d7be 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -7091,7 +7091,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
else if ( eAlign == ALIGN_TOP )
aOffset.AdjustY(GetFontInstance()->mxFontMetric->GetAscent() );
- tools::Rectangle aRectangle;
+ basegfx::B2DRectangle aRectangle;
nIndex = 0;
while (rLayout.GetNextGlyph(&pGlyph, aPos, nIndex, &pGlyphFont))
{
@@ -7109,7 +7109,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
else
{
aAdjOffset = basegfx::B2DPoint(aOffset.X(), aOffset.Y());
- aAdjOffset.adjustX(aRectangle.Left() + (aRectangle.GetWidth() - aEmphasisMark.GetWidth()) / 2 );
+ aAdjOffset.adjustX(aRectangle.getMinX() + (aRectangle.getWidth() - aEmphasisMark.GetWidth()) / 2 );
}
aAdjOffset = aRotScale.transform( aAdjOffset );
@@ -9125,9 +9125,15 @@ void PDFWriterImpl::writeReferenceXObject(const ReferenceXObjectEmit& rEmit)
}
double aOrigin[2] = { 0.0, 0.0 };
- if (auto* pArray = dynamic_cast<filter::PDFArrayElement*>(pPage->Lookup("MediaBox"_ostr)))
+
+ // tdf#160714 use crop box for bounds of embedded PDF object
+ // If there is no crop box, fallback to the media box just to be safe.
+ auto* pBoundsArray = dynamic_cast<filter::PDFArrayElement*>(pPage->Lookup("CropBox"_ostr));
+ if (!pBoundsArray)
+ pBoundsArray = dynamic_cast<filter::PDFArrayElement*>(pPage->Lookup("MediaBox"_ostr));
+ if (pBoundsArray)
{
- const auto& rElements = pArray->GetElements();
+ const auto& rElements = pBoundsArray->GetElements();
if (rElements.size() >= 4)
{
// get x1, y1 of the rectangle.
@@ -9240,9 +9246,9 @@ void PDFWriterImpl::writeReferenceXObject(const ReferenceXObjectEmit& rEmit)
// Now transform the object: rotate around the center and make sure that the rotation
// doesn't affect the aspect ratio.
basegfx::B2DHomMatrix aMat;
- aMat.translate(-0.5 * aBBox.getWidth() - aOrigin[0], -0.5 * aBBox.getHeight() - aOrigin[1]);
+ aMat.translate((-0.5 * aBBox.getWidth() / fMagicScaleFactor) - aOrigin[0], (-0.5 * aBBox.getHeight() / fMagicScaleFactor) - aOrigin[1]);
aMat.rotate(basegfx::deg2rad(nAngle));
- aMat.translate(0.5 * nWidth, 0.5 * nHeight);
+ aMat.translate(0.5 * nWidth / fMagicScaleFactor, 0.5 * nHeight / fMagicScaleFactor);
aLine.append(" /Matrix [ ");
aLine.append(aMat.a());
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index af281127ba..28138c3f61 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -214,12 +214,18 @@ bool SalLayout::GetOutline(basegfx::B2DPolyPolygonVector& rVector) const
return (bAllOk && bOneOk);
}
+// No need to expand to the next pixel, when the character only covers its tiny fraction
+static double trimInsignificant(double n)
+{
+ return std::abs(n) >= 0x1p53 ? n : std::round(n * 1e5) / 1e5;
+}
+
bool SalLayout::GetBoundRect(tools::Rectangle& rRect) const
{
bool bRet = false;
- rRect.SetEmpty();
- tools::Rectangle aRectangle;
+ basegfx::B2DRectangle aUnion;
+ basegfx::B2DRectangle aRectangle;
basegfx::B2DPoint aPos;
const GlyphItem* pGlyph;
@@ -230,22 +236,28 @@ bool SalLayout::GetBoundRect(tools::Rectangle& rRect) const
// get bounding rectangle of individual glyph
if (pGlyph->GetGlyphBoundRect(pGlyphFont, aRectangle))
{
- if (!aRectangle.IsEmpty())
+ if (!aRectangle.isEmpty())
{
- aRectangle.AdjustLeft(std::floor(aPos.getX()));
- aRectangle.AdjustRight(std::ceil(aPos.getX()));
- aRectangle.AdjustTop(std::floor(aPos.getY()));
- aRectangle.AdjustBottom(std::ceil(aPos.getY()));
-
+ aRectangle.transform(basegfx::utils::createTranslateB2DHomMatrix(aPos));
// merge rectangle
- if (rRect.IsEmpty())
- rRect = aRectangle;
- else
- rRect.Union(aRectangle);
+ aUnion.expand(aRectangle);
}
bRet = true;
}
}
+ if (aUnion.isEmpty())
+ {
+ rRect = {};
+ }
+ else
+ {
+ double l = rtl::math::approxFloor(trimInsignificant(aUnion.getMinX())),
+ t = rtl::math::approxFloor(trimInsignificant(aUnion.getMinY())),
+ r = rtl::math::approxCeil(trimInsignificant(aUnion.getMaxX())),
+ b = rtl::math::approxCeil(trimInsignificant(aUnion.getMaxY()));
+ assert(std::isfinite(l) && std::isfinite(t) && std::isfinite(r) && std::isfinite(b));
+ rRect = tools::Rectangle(l, t, r, b);
+ }
return bRet;
}
@@ -292,7 +304,7 @@ void GenericSalLayout::Justify(double nNewWidth)
std::vector<GlyphItem>::iterator pGlyphIter;
// count stretchable glyphs
int nStretchable = 0;
- double nMaxGlyphWidth = 0;
+ double nMaxGlyphWidth = 0.0;
for(pGlyphIter = m_GlyphItems.begin(); pGlyphIter != pGlyphIterRight; ++pGlyphIter)
{
if( !pGlyphIter->IsInCluster() )
@@ -303,7 +315,7 @@ void GenericSalLayout::Justify(double nNewWidth)
// move rightmost glyph to requested position
nOldWidth -= pGlyphIterRight->origWidth();
- if( nOldWidth <= 0 )
+ if( nOldWidth <= 0.0 )
return;
if( nNewWidth < nMaxGlyphWidth)
nNewWidth = nMaxGlyphWidth;
@@ -312,10 +324,10 @@ void GenericSalLayout::Justify(double nNewWidth)
// justify glyph widths and positions
double nDiffWidth = nNewWidth - nOldWidth;
- if( nDiffWidth >= 0) // expanded case
+ if( nDiffWidth >= 0.0 ) // expanded case
{
// expand width by distributing space between glyphs evenly
- int nDeltaSum = 0;
+ double nDeltaSum = 0.0;
for( pGlyphIter = m_GlyphItems.begin(); pGlyphIter != pGlyphIterRight; ++pGlyphIter )
{
// move glyph to justified position
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 2086db7f63..9c04373159 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -951,7 +951,7 @@ void OutputDevice::ImplDrawEmphasisMarks( SalLayout& rSalLayout )
aOffset += Point( nEmphasisWidth2, nEmphasisHeight2 );
basegfx::B2DPoint aOutPoint;
- tools::Rectangle aRectangle;
+ basegfx::B2DRectangle aRectangle;
const GlyphItem* pGlyph;
const LogicalFontInstance* pGlyphFont;
int nStart = 0;
@@ -971,7 +971,7 @@ void OutputDevice::ImplDrawEmphasisMarks( SalLayout& rSalLayout )
else
{
aAdjPoint = aOffset;
- aAdjPoint.AdjustX(aRectangle.Left() + (aRectangle.GetWidth() - aEmphasisMark.GetWidth()) / 2 );
+ aAdjPoint.AdjustX(aRectangle.getMinX() + (aRectangle.getWidth() - aEmphasisMark.GetWidth()) / 2 );
}
if ( mpFontInstance->mnOrientation )
diff --git a/vcl/source/treelist/iconviewimpl.cxx b/vcl/source/treelist/iconviewimpl.cxx
index 048e193d4f..35025d1c81 100644
--- a/vcl/source/treelist/iconviewimpl.cxx
+++ b/vcl/source/treelist/iconviewimpl.cxx
@@ -467,6 +467,7 @@ void IconViewImpl::SyncVerThumb()
void IconViewImpl::UpdateAll()
{
FindMostRight();
+ AdjustScrollBars(m_aOutputSize);
SyncVerThumb();
FillView();
ShowVerSBar();
diff --git a/vcl/source/window/accessibility.cxx b/vcl/source/window/accessibility.cxx
index 3c6103ac31..295a5c3878 100644
--- a/vcl/source/window/accessibility.cxx
+++ b/vcl/source/window/accessibility.cxx
@@ -69,7 +69,7 @@ css::uno::Reference< css::accessibility::XAccessible > Window::GetAccessible( bo
*/
if ( !mpWindowImpl )
return css::uno::Reference< css::accessibility::XAccessible >();
- if ( !mpWindowImpl->mxAccessible.is() && bCreate )
+ if (!mpWindowImpl->mxAccessible.is() && !mpWindowImpl->mbInDispose && bCreate)
mpWindowImpl->mxAccessible = CreateAccessible();
return mpWindowImpl->mxAccessible;
diff --git a/vcl/source/window/legacyaccessibility.cxx b/vcl/source/window/legacyaccessibility.cxx
index 346e1fdc8f..a0f4aff339 100644
--- a/vcl/source/window/legacyaccessibility.cxx
+++ b/vcl/source/window/legacyaccessibility.cxx
@@ -109,7 +109,7 @@ Window* Window::getLegacyNonLayoutAccessibleRelationLabelFor() const
static Window* ImplGetLabeledBy( Window* pFrameWindow, WindowType nMyType, Window* pLabeled )
{
Window* pWindow = nullptr;
- if ( (nMyType != WindowType::GROUPBOX) && (nMyType != WindowType::FIXEDLINE) )
+ if (pFrameWindow && nMyType != WindowType::GROUPBOX && nMyType != WindowType::FIXEDLINE)
{
// search for a control that labels this window
// a label is considered the last fixed text, fixed line or group box
diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx
index 9c5f519f7c..c001b6e740 100644
--- a/vcl/source/window/printdlg.cxx
+++ b/vcl/source/window/printdlg.cxx
@@ -122,7 +122,7 @@ void PrintDialog::PrintPreviewWindow::Paint(vcl::RenderContext& rRenderContext,
{
rRenderContext.Push();
weld::SetPointFont(rRenderContext, rRenderContext.GetSettings().GetStyleSettings().GetLabelFont());
-
+ rRenderContext.SetTextColor(rRenderContext.GetSettings().GetStyleSettings().GetLabelTextColor());
rRenderContext.SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetDialogColor()));
rRenderContext.Erase();
diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx
index f996b4359b..8c097c526c 100644
--- a/vcl/unx/gtk3/gtkframe.cxx
+++ b/vcl/unx/gtk3/gtkframe.cxx
@@ -3953,12 +3953,24 @@ void GtkSalFrame::signalRealize(GtkWidget*, gpointer frame)
}
AbsoluteScreenPixelRectangle aFloatRect = FloatingWindow::ImplConvertToAbsPos(pVclParent, pThis->m_aFloatRect);
- if (gdk_window_get_window_type(widget_get_surface(pThis->m_pParent->m_pWindow)) != GDK_WINDOW_TOPLEVEL)
+ switch (gdk_window_get_window_type(widget_get_surface(pThis->m_pParent->m_pWindow)))
{
- // See tdf#152155 for an example
- gtk_coord nX(0), nY(0.0);
- gtk_widget_translate_coordinates(pThis->m_pParent->m_pWindow, widget_get_toplevel(pThis->m_pParent->m_pWindow), 0, 0, &nX, &nY);
- aFloatRect.Move(nX, nY);
+ case GDK_WINDOW_TOPLEVEL:
+ break;
+ case GDK_WINDOW_CHILD:
+ {
+ // See tdf#152155 for an example
+ gtk_coord nX(0), nY(0.0);
+ gtk_widget_translate_coordinates(pThis->m_pParent->m_pWindow, widget_get_toplevel(pThis->m_pParent->m_pWindow), 0, 0, &nX, &nY);
+ aFloatRect.Move(nX, nY);
+ break;
+ }
+ default:
+ {
+ // See tdf#154072 for an example
+ aFloatRect.Move(-pThis->m_pParent->maGeometry.x(), -pThis->m_pParent->maGeometry.y());
+ break;
+ }
}
GdkRectangle rect {static_cast<int>(aFloatRect.Left()), static_cast<int>(aFloatRect.Top()),
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index b8da4f7b7a..a899fc16c6 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -5505,8 +5505,9 @@ public:
{
GtkBox *pBox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6));
GtkWidget *pLabel = gtk_label_new_with_mnemonic(MapToGtkAccelerator(rStr).getStr());
+ gtk_label_set_xalign(GTK_LABEL(pLabel), 0.0);
pItem = eCheckRadioFalse != TRISTATE_INDET ? gtk_check_menu_item_new() : gtk_menu_item_new();
- gtk_box_pack_start(pBox, pImage, true, true, 0);
+ gtk_box_pack_start(pBox, pImage, false, true, 0);
gtk_box_pack_start(pBox, pLabel, true, true, 0);
gtk_container_add(GTK_CONTAINER(pItem), GTK_WIDGET(pBox));
gtk_widget_show_all(pItem);
@@ -8745,6 +8746,11 @@ public:
gtk_widget_set_size_request(GTK_WIDGET(m_pScrollbar), nThickness, -1);
}
+ virtual void set_scroll_swap_arrows(bool /* bSwap */) override
+ {
+ // Related: tdf#93352 do nothing since GtkScrollbar has no arrows
+ }
+
virtual ~GtkInstanceScrollbar() override
{
g_signal_handler_disconnect(m_pAdjustment, m_nAdjustChangedSignalId);
@@ -14834,6 +14840,32 @@ private:
}
#endif
+ static gboolean search_equal_func(GtkTreeModel *model,
+ int column,
+ const char *key,
+ GtkTreeIter *iter,
+ gpointer /*user_data*/)
+ {
+ GValue aValue = G_VALUE_INIT;
+ gtk_tree_model_get_value(model, iter, column, &aValue);
+
+ GValue aStringValue = G_VALUE_INIT;
+ g_value_init(&aStringValue, G_TYPE_STRING);
+ const bool fail = !g_value_transform(&aValue, &aStringValue);
+ g_value_unset(&aValue);
+ if (fail)
+ return true;
+
+ bool bNoMatch(true);
+ if (const char *str = g_value_get_string(&aStringValue))
+ {
+ const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetLocaleI18nHelper();
+ bNoMatch = !rI18nHelper.MatchString(OUString::fromUtf8(key), OUString::fromUtf8(str));
+ }
+ g_value_unset(&aStringValue);
+ return bNoMatch;
+ }
+
public:
GtkInstanceTreeView(GtkTreeView* pTreeView, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
: GtkInstanceWidget(GTK_WIDGET(pTreeView), pBuilder, bTakeOwnership)
@@ -14965,6 +14997,10 @@ public:
m_nRowDeletedSignalId = g_signal_connect(m_pTreeModel, "row-deleted", G_CALLBACK(signalRowDeleted), this);
m_nRowInsertedSignalId = g_signal_connect(m_pTreeModel, "row-inserted", G_CALLBACK(signalRowInserted), this);
+
+ // tdf#160028 LibreOffice embeds RTL/LTR direction markers in currency strings, which defeats the
+ // default gtk search mechanism, so switch in our one here
+ gtk_tree_view_set_search_equal_func(m_pTreeView, search_equal_func, nullptr, nullptr);
}
virtual void connect_query_tooltip(const Link<const weld::TreeIter&, OUString>& rLink) override
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 1eed596e6c..bd93ad6bf4 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -3589,7 +3589,7 @@ static bool HandleAltNumPadCode(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lPar
if (!(keyFlags & KF_REPEAT))
state.clear();
state.started = true;
- return true;
+ return false; // This must be processed further - e.g., to show accelerators
}
if (!state.started)
diff --git a/vcl/workben/listglyphs.cxx b/vcl/workben/listglyphs.cxx
index def2ff8181..341006d433 100644
--- a/vcl/workben/listglyphs.cxx
+++ b/vcl/workben/listglyphs.cxx
@@ -120,7 +120,7 @@ int ListGlyphs::Main()
nChar = pCharMap->GetNextChar(nChar))
{
auto nGlyphIndex = pFontInstance->GetGlyphIndex(nChar);
- tools::Rectangle aGlyphBounds;
+ basegfx::B2DRectangle aGlyphBounds;
pFontInstance->GetGlyphBoundRect(nGlyphIndex, aGlyphBounds, false);
std::cout << "Codepoint: " << pFontFace->GetGlyphName(nGlyphIndex)
<< "; glyph bounds: " << aGlyphBounds << "\n";