summaryrefslogtreecommitdiff
path: root/vcl/source/gdi/sallayout.cxx
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2024-03-29 20:15:06 +0500
committerMike Kaganski <mike.kaganski@collabora.com>2024-04-01 13:05:56 +0200
commit8962141a12c966b2d891829925e6203bf8d51852 (patch)
tree9b56088816775fb7907f5fb9c2c91f63998571d8 /vcl/source/gdi/sallayout.cxx
parent7c18a0bb37fc2cd50bd3fa4386b02d88fbedb773 (diff)
tdf#160430: Fix glyph bounds calculation, and use basegfx::B2DRectangle
... instead of tools::Rectangle. Several problems were there: 1. First, a horizontal bounding rectangle was calculated, with due rounding; and then the result was rotated, and after that, rounded again. That made the resulting rotated rectangle coordinates very imprecise. 2. Also, ceil/floor was applied without normalization; and in case of rotated font, that meant, that sometimes the range could be not expanded to cover partially covered pixels, but instead collapsed. 3. The rotation to angles other than 90 degree multiples was done incorrectly, resulting in cut off parts of characters. 4. For 90 degrees, the imprecise result of sin/cos converted 0.0 into values like 3e-16, which then could be ceil'ed up to 1. Using B2DRectangle and its transform allows to simplify and fix the calculations easily, and avoids premature rounding. Render of rotated text of small size is more stable with this change. Change-Id: Idffd74b9937feb2418ab76a8d325fdaf4ff841b7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165553 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'vcl/source/gdi/sallayout.cxx')
-rw-r--r--vcl/source/gdi/sallayout.cxx24
1 files changed, 12 insertions, 12 deletions
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index af281127ba86..d1a29de327ff 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -214,12 +214,15 @@ 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::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 +233,19 @@ 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;
}
}
+ rRect = tools::Rectangle(rtl::math::approxFloor(trimInsignificant(aUnion.getMinX())),
+ rtl::math::approxFloor(trimInsignificant(aUnion.getMinY())),
+ rtl::math::approxCeil(trimInsignificant(aUnion.getMaxX())),
+ rtl::math::approxCeil(trimInsignificant(aUnion.getMaxY())));
return bRet;
}