vcl/source/gdi/pdfwriter_impl.cxx | 71 +++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 23 deletions(-)
New commits: commit 155028fa20d89713ec82168e5c7570333a47136d Author: Khaled Hosny <kha...@aliftype.com> AuthorDate: Fri Mar 17 23:42:54 2023 +0200 Commit: خالد حسني <kha...@aliftype.com> CommitDate: Fri Mar 17 23:08:01 2023 +0000 tdf#154235: Fix underline position in PDF export Change-Id: I9a15646cc6a69ca7226f06ecc56a28fba3fa96db Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149071 Tested-by: Jenkins Reviewed-by: خالد حسني <kha...@aliftype.com> diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 537db70e5b52..9e0f370dbc8a 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -7391,15 +7391,15 @@ void PDFWriterImpl::drawStraightTextLine( OStringBuffer& aLine, tools::Long nWid { if ( !pFontInstance->mxFontMetric->GetAboveUnderlineSize() ) ImplInitAboveTextLineSize(); - nLineHeight = HCONV( pFontInstance->mxFontMetric->GetAboveUnderlineSize() ); - nLinePos = HCONV( pFontInstance->mxFontMetric->GetAboveUnderlineOffset() ); + nLineHeight = pFontInstance->mxFontMetric->GetAboveUnderlineSize(); + nLinePos = pFontInstance->mxFontMetric->GetAboveUnderlineOffset(); } else { if ( !pFontInstance->mxFontMetric->GetUnderlineSize() ) ImplInitTextLineSize(); - nLineHeight = HCONV( pFontInstance->mxFontMetric->GetUnderlineSize() ); - nLinePos = HCONV( pFontInstance->mxFontMetric->GetUnderlineOffset() ); + nLineHeight = pFontInstance->mxFontMetric->GetUnderlineSize(); + nLinePos = pFontInstance->mxFontMetric->GetUnderlineOffset(); } break; case LINESTYLE_BOLD: @@ -7412,16 +7412,15 @@ void PDFWriterImpl::drawStraightTextLine( OStringBuffer& aLine, tools::Long nWid { if ( !pFontInstance->mxFontMetric->GetAboveBoldUnderlineSize() ) ImplInitAboveTextLineSize(); - nLineHeight = HCONV( pFontInstance->mxFontMetric->GetAboveBoldUnderlineSize() ); - nLinePos = HCONV( pFontInstance->mxFontMetric->GetAboveBoldUnderlineOffset() ); + nLineHeight = pFontInstance->mxFontMetric->GetAboveBoldUnderlineSize(); + nLinePos = pFontInstance->mxFontMetric->GetAboveBoldUnderlineOffset(); } else { if ( !pFontInstance->mxFontMetric->GetBoldUnderlineSize() ) ImplInitTextLineSize(); - nLineHeight = HCONV( pFontInstance->mxFontMetric->GetBoldUnderlineSize() ); - nLinePos = HCONV( pFontInstance->mxFontMetric->GetBoldUnderlineOffset() ); - nLinePos += nLineHeight/2; + nLineHeight = pFontInstance->mxFontMetric->GetBoldUnderlineSize(); + nLinePos = pFontInstance->mxFontMetric->GetBoldUnderlineOffset(); } break; case LINESTYLE_DOUBLE: @@ -7429,17 +7428,17 @@ void PDFWriterImpl::drawStraightTextLine( OStringBuffer& aLine, tools::Long nWid { if ( !pFontInstance->mxFontMetric->GetAboveDoubleUnderlineSize() ) ImplInitAboveTextLineSize(); - nLineHeight = HCONV( pFontInstance->mxFontMetric->GetAboveDoubleUnderlineSize() ); - nLinePos = HCONV( pFontInstance->mxFontMetric->GetAboveDoubleUnderlineOffset1() ); - nLinePos2 = HCONV( pFontInstance->mxFontMetric->GetAboveDoubleUnderlineOffset2() ); + nLineHeight = pFontInstance->mxFontMetric->GetAboveDoubleUnderlineSize(); + nLinePos = pFontInstance->mxFontMetric->GetAboveDoubleUnderlineOffset1(); + nLinePos2 = pFontInstance->mxFontMetric->GetAboveDoubleUnderlineOffset2(); } else { if ( !pFontInstance->mxFontMetric->GetDoubleUnderlineSize() ) ImplInitTextLineSize(); - nLineHeight = HCONV( pFontInstance->mxFontMetric->GetDoubleUnderlineSize() ); - nLinePos = HCONV( pFontInstance->mxFontMetric->GetDoubleUnderlineOffset1() ); - nLinePos2 = HCONV( pFontInstance->mxFontMetric->GetDoubleUnderlineOffset2() ); + nLineHeight = pFontInstance->mxFontMetric->GetDoubleUnderlineSize(); + nLinePos = pFontInstance->mxFontMetric->GetDoubleUnderlineOffset1(); + nLinePos2 = pFontInstance->mxFontMetric->GetDoubleUnderlineOffset2(); } break; default: @@ -7449,6 +7448,23 @@ void PDFWriterImpl::drawStraightTextLine( OStringBuffer& aLine, tools::Long nWid if ( !nLineHeight ) return; + // tdf#154235 + // nLinePos/nLinePos2 is the distance from baseline to the top of the line, + // while in PDF we stroke the line so the position is to the middle of the + // line, we add half of nLineHeight to account for that. + auto nOffset = nLineHeight / 2; + if (m_aCurrentPDFState.m_aFont.IsOutline() && eTextLine == LINESTYLE_SINGLE) + { + // Except when outlining, as now we are drawing a rectangle, so + // nLinePos is the bottom of the rectangle, so need to add nLineHeight + // to it. + nOffset = nLineHeight; + } + + nLineHeight = HCONV(nLineHeight); + nLinePos = HCONV(nLinePos + nOffset); + nLinePos2 = HCONV(nLinePos2 + nOffset); + // outline attribute ? if (m_aCurrentPDFState.m_aFont.IsOutline() && eTextLine == LINESTYLE_SINGLE) { @@ -7460,7 +7476,7 @@ void PDFWriterImpl::drawStraightTextLine( OStringBuffer& aLine, tools::Long nWid // draw rectangle instead aLine.append( "0 " ); - m_aPages.back().appendMappedLength( static_cast<sal_Int32>(-nLinePos * 1.5), aLine ); + m_aPages.back().appendMappedLength( static_cast<sal_Int32>(-nLinePos), aLine ); aLine.append( " " ); m_aPages.back().appendMappedLength( static_cast<sal_Int32>(nWidth), aLine, false ); aLine.append( ' ' ); @@ -7469,6 +7485,7 @@ void PDFWriterImpl::drawStraightTextLine( OStringBuffer& aLine, tools::Long nWid return; } + m_aPages.back().appendMappedLength( static_cast<sal_Int32>(nLineHeight), aLine ); aLine.append( " w " ); appendStrokingColor( aColor, aLine ); @@ -7575,21 +7592,21 @@ void PDFWriterImpl::drawStrikeoutLine( OStringBuffer& aLine, tools::Long nWidth, case STRIKEOUT_SINGLE: if ( !pFontInstance->mxFontMetric->GetStrikeoutSize() ) ImplInitTextLineSize(); - nLineHeight = HCONV( pFontInstance->mxFontMetric->GetStrikeoutSize() ); - nLinePos = HCONV( pFontInstance->mxFontMetric->GetStrikeoutOffset() ); + nLineHeight = pFontInstance->mxFontMetric->GetStrikeoutSize(); + nLinePos = pFontInstance->mxFontMetric->GetStrikeoutOffset(); break; case STRIKEOUT_BOLD: if ( !pFontInstance->mxFontMetric->GetBoldStrikeoutSize() ) ImplInitTextLineSize(); - nLineHeight = HCONV( pFontInstance->mxFontMetric->GetBoldStrikeoutSize() ); - nLinePos = HCONV( pFontInstance->mxFontMetric->GetBoldStrikeoutOffset() ); + nLineHeight = pFontInstance->mxFontMetric->GetBoldStrikeoutSize(); + nLinePos = pFontInstance->mxFontMetric->GetBoldStrikeoutOffset(); break; case STRIKEOUT_DOUBLE: if ( !pFontInstance->mxFontMetric->GetDoubleStrikeoutSize() ) ImplInitTextLineSize(); - nLineHeight = HCONV( pFontInstance->mxFontMetric->GetDoubleStrikeoutSize() ); - nLinePos = HCONV( pFontInstance->mxFontMetric->GetDoubleStrikeoutOffset1() ); - nLinePos2 = HCONV( pFontInstance->mxFontMetric->GetDoubleStrikeoutOffset2() ); + nLineHeight = pFontInstance->mxFontMetric->GetDoubleStrikeoutSize(); + nLinePos = pFontInstance->mxFontMetric->GetDoubleStrikeoutOffset1(); + nLinePos2 = pFontInstance->mxFontMetric->GetDoubleStrikeoutOffset2(); break; default: break; @@ -7598,6 +7615,14 @@ void PDFWriterImpl::drawStrikeoutLine( OStringBuffer& aLine, tools::Long nWidth, if ( !nLineHeight ) return; + // tdf#154235 + // nLinePos/nLinePos2 is the distance from baseline to the bottom of the line, + // while in PDF we stroke the line so the position is to the middle of the + // line, we add half of nLineHeight to account for that. + nLinePos = HCONV(nLinePos + nLineHeight / 2); + nLinePos2 = HCONV(nLinePos2 + nLineHeight / 2); + nLineHeight = HCONV(nLineHeight); + m_aPages.back().appendMappedLength( static_cast<sal_Int32>(nLineHeight), aLine ); aLine.append( " w " ); appendStrokingColor( aColor, aLine );