From e3cf16e6fbf8d39cad8762f002b6db1d4f61ed36 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 07:03:24 +0200 Subject: Merging upstream version 4:24.2.3. Signed-off-by: Daniel Baumann --- vcl/source/app/salvtables.cxx | 2 ++ vcl/source/app/svmain.cxx | 2 +- vcl/source/bitmap/BitmapEx.cxx | 11 ++++--- vcl/source/control/scrbar.cxx | 6 ++-- vcl/source/filter/webp/reader.cxx | 4 +-- vcl/source/font/LogicalFontInstance.cxx | 53 +++++++++++++++---------------- vcl/source/font/fontcache.cxx | 4 +-- vcl/source/gdi/CommonSalLayout.cxx | 6 ++-- vcl/source/gdi/pdfwriter_impl.cxx | 18 +++++++---- vcl/source/gdi/sallayout.cxx | 44 +++++++++++++++---------- vcl/source/outdev/font.cxx | 4 +-- vcl/source/treelist/iconviewimpl.cxx | 1 + vcl/source/window/accessibility.cxx | 2 +- vcl/source/window/legacyaccessibility.cxx | 2 +- vcl/source/window/printdlg.cxx | 2 +- 15 files changed, 92 insertions(+), 69 deletions(-) (limited to 'vcl/source') 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 #include +#include + 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(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(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(pPage->Lookup("CropBox"_ostr)); + if (!pBoundsArray) + pBoundsArray = dynamic_cast(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::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(); -- cgit v1.2.3