summaryrefslogtreecommitdiffstats
path: root/drawinglayer
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 11:47:06 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 11:47:06 +0000
commit8ceff95c69cf9bd9ff5ab3a4b5689925b8bd6a59 (patch)
treeca2b0cc4fba88107f5f6e740285184a061011866 /drawinglayer
parentAdding debian version 4:24.2.3-2. (diff)
downloadlibreoffice-8ceff95c69cf9bd9ff5ab3a4b5689925b8bd6a59.tar.xz
libreoffice-8ceff95c69cf9bd9ff5ab3a4b5689925b8bd6a59.zip
Merging upstream version 4:24.2.4.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/primitive2d/textlayoutdevice.cxx67
-rw-r--r--drawinglayer/source/processor2d/vclprocessor2d.cxx28
2 files changed, 75 insertions, 20 deletions
diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index 1c551ce013..9de6340769 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -22,6 +22,8 @@
#include <algorithm>
#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <drawinglayer/attribute/fontattribute.hxx>
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
#include <comphelper/processfactory.hxx>
@@ -162,56 +164,78 @@ TextLayouterDevice::TextLayouterDevice()
TextLayouterDevice::~TextLayouterDevice() COVERITY_NOEXCEPT_FALSE { releaseGlobalVirtualDevice(); }
-void TextLayouterDevice::setFont(const vcl::Font& rFont) { mrDevice.SetFont(rFont); }
+void TextLayouterDevice::setFont(const vcl::Font& rFont)
+{
+ mrDevice.SetFont(rFont);
+ mnFontScalingFixX = 1.0;
+ mnFontScalingFixY = 1.0;
+}
void TextLayouterDevice::setFontAttribute(const attribute::FontAttribute& rFontAttribute,
double fFontScaleX, double fFontScaleY,
const css::lang::Locale& rLocale)
{
- setFont(getVclFontFromFontAttribute(rFontAttribute, fFontScaleX, fFontScaleY, 0.0, rLocale));
+ vcl::Font aFont
+ = getVclFontFromFontAttribute(rFontAttribute, fFontScaleX, fFontScaleY, 0.0, rLocale);
+ setFont(aFont);
+ Size aFontSize = aFont.GetFontSize();
+ if (aFontSize.Height())
+ {
+ mnFontScalingFixY = fFontScaleY / aFontSize.Height();
+ // aFontSize.Width() is 0 for uninformly scaled fonts: see getVclFontFromFontAttribute
+ mnFontScalingFixX
+ = fFontScaleX / (aFontSize.Width() ? aFontSize.Width() : aFontSize.Height());
+ }
+ else
+ {
+ mnFontScalingFixX = mnFontScalingFixY = 1.0;
+ }
}
double TextLayouterDevice::getOverlineOffset() const
{
const ::FontMetric& rMetric = mrDevice.GetFontMetric();
double fRet = (rMetric.GetInternalLeading() / 2.0) - rMetric.GetAscent();
- return fRet;
+ return fRet * mnFontScalingFixY;
}
double TextLayouterDevice::getUnderlineOffset() const
{
const ::FontMetric& rMetric = mrDevice.GetFontMetric();
double fRet = rMetric.GetDescent() / 2.0;
- return fRet;
+ return fRet * mnFontScalingFixY;
}
double TextLayouterDevice::getStrikeoutOffset() const
{
const ::FontMetric& rMetric = mrDevice.GetFontMetric();
double fRet = (rMetric.GetAscent() - rMetric.GetInternalLeading()) / 3.0;
- return fRet;
+ return fRet * mnFontScalingFixY;
}
double TextLayouterDevice::getOverlineHeight() const
{
const ::FontMetric& rMetric = mrDevice.GetFontMetric();
double fRet = rMetric.GetInternalLeading() / 2.5;
- return fRet;
+ return fRet * mnFontScalingFixY;
}
double TextLayouterDevice::getUnderlineHeight() const
{
const ::FontMetric& rMetric = mrDevice.GetFontMetric();
double fRet = rMetric.GetDescent() / 4.0;
- return fRet;
+ return fRet * mnFontScalingFixY;
}
-double TextLayouterDevice::getTextHeight() const { return mrDevice.GetTextHeight(); }
+double TextLayouterDevice::getTextHeight() const
+{
+ return mrDevice.GetTextHeight() * mnFontScalingFixY;
+}
double TextLayouterDevice::getTextWidth(const OUString& rText, sal_uInt32 nIndex,
sal_uInt32 nLength) const
{
- return mrDevice.GetTextWidth(rText, nIndex, nLength);
+ return mrDevice.GetTextWidth(rText, nIndex, nLength) * mnFontScalingFixX;
}
void TextLayouterDevice::getTextOutlines(basegfx::B2DPolyPolygonVector& rB2DPolyPolyVector,
@@ -245,6 +269,13 @@ void TextLayouterDevice::getTextOutlines(basegfx::B2DPolyPolygonVector& rB2DPoly
{
mrDevice.GetTextOutlines(rB2DPolyPolyVector, rText, nIndex, nIndex, nLength);
}
+ if (!rtl_math_approxEqual(mnFontScalingFixY, 1.0)
+ || !rtl_math_approxEqual(mnFontScalingFixX, 1.0))
+ {
+ auto scale = basegfx::utils::createScaleB2DHomMatrix(mnFontScalingFixX, mnFontScalingFixY);
+ for (auto& poly : rB2DPolyPolyVector)
+ poly.transform(scale);
+ }
}
basegfx::B2DRange TextLayouterDevice::getTextBoundRect(const OUString& rText, sal_uInt32 nIndex,
@@ -260,15 +291,15 @@ basegfx::B2DRange TextLayouterDevice::getTextBoundRect(const OUString& rText, sa
if (nTextLength)
{
- ::tools::Rectangle aRect;
-
+ basegfx::B2DRange aRect;
mrDevice.GetTextBoundRect(aRect, rText, nIndex, nIndex, nLength);
-
- // #i104432#, #i102556# take empty results into account
- if (!aRect.IsEmpty())
+ if (!rtl_math_approxEqual(mnFontScalingFixY, 1.0)
+ || !rtl_math_approxEqual(mnFontScalingFixX, 1.0))
{
- return vcl::unotools::b2DRectangleFromRectangle(aRect);
+ aRect.transform(
+ basegfx::utils::createScaleB2DHomMatrix(mnFontScalingFixX, mnFontScalingFixY));
}
+ return aRect;
}
return basegfx::B2DRange();
@@ -277,13 +308,13 @@ basegfx::B2DRange TextLayouterDevice::getTextBoundRect(const OUString& rText, sa
double TextLayouterDevice::getFontAscent() const
{
const ::FontMetric& rMetric = mrDevice.GetFontMetric();
- return rMetric.GetAscent();
+ return rMetric.GetAscent() * mnFontScalingFixY;
}
double TextLayouterDevice::getFontDescent() const
{
const ::FontMetric& rMetric = mrDevice.GetFontMetric();
- return rMetric.GetDescent();
+ return rMetric.GetDescent() * mnFontScalingFixY;
}
void TextLayouterDevice::addTextRectActions(const ::tools::Rectangle& rRectangle,
@@ -311,7 +342,7 @@ std::vector<double> TextLayouterDevice::getTextArray(const OUString& rText, sal_
mrDevice.GetTextArray(rText, &aArray, nIndex, nTextLength, bCaret);
aRetval.reserve(aArray.size());
for (size_t i = 0, nEnd = aArray.size(); i < nEnd; ++i)
- aRetval.push_back(aArray[i]);
+ aRetval.push_back(aArray[i] * mnFontScalingFixX);
}
return aRetval;
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 2c3521ace0..a1c23c91db 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -182,7 +182,8 @@ void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(
}
// Don't draw fonts without height
- if (aFont.GetFontHeight() <= 0)
+ Size aResultFontSize = aFont.GetFontSize();
+ if (aResultFontSize.Height() <= 0)
return;
// set FillColor Attribute
@@ -408,7 +409,30 @@ void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(
else
{
const basegfx::B2DPoint aPoint(aLocalTransform * basegfx::B2DPoint(0.0, 0.0));
- aStartPoint = Point(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY()));
+ double aPointX = aPoint.getX(), aPointY = aPoint.getY();
+
+ // aFont has an integer size; we must scale a bit for precision
+ double nFontScalingFixY = aFontScaling.getY() / aResultFontSize.Height();
+ double nFontScalingFixX = aFontScaling.getX()
+ / (aResultFontSize.Width() ? aResultFontSize.Width()
+ : aResultFontSize.Height());
+
+ if (!rtl_math_approxEqual(nFontScalingFixY, 1.0)
+ || !rtl_math_approxEqual(nFontScalingFixX, 1.0))
+ {
+ MapMode aMapMode = mpOutputDevice->GetMapMode();
+ aMapMode.SetScaleX(aMapMode.GetScaleX() * nFontScalingFixX);
+ aMapMode.SetScaleY(aMapMode.GetScaleY() * nFontScalingFixY);
+
+ mpOutputDevice->Push(vcl::PushFlags::MAPMODE);
+ mpOutputDevice->SetRelativeMapMode(aMapMode);
+ bChangeMapMode = true;
+
+ aPointX /= nFontScalingFixX;
+ aPointY /= nFontScalingFixY;
+ }
+
+ aStartPoint = Point(basegfx::fround(aPointX), basegfx::fround(aPointY));
}
// tdf#152990 set the font after the MapMode is (potentially) set so canvas uses the desired