summaryrefslogtreecommitdiffstats
path: root/vcl/source/gdi/sallayout.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/gdi/sallayout.cxx')
-rw-r--r--vcl/source/gdi/sallayout.cxx44
1 files changed, 28 insertions, 16 deletions
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