summaryrefslogtreecommitdiffstats
path: root/vcl/source/gdi
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/gdi')
-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
3 files changed, 43 insertions, 25 deletions
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