summaryrefslogtreecommitdiff
path: root/vcl/source
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2018-03-21 16:54:10 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2018-03-23 09:25:42 +0100
commit90fb652ebbc4b16ae5001140076f52209e913345 (patch)
tree35238e8dfbd29c6535867acf944fe70822e3e437 /vcl/source
parentdeb5db7bf6d45338c9b6f6f4a1d62fba168b7a85 (diff)
tdf#115117: Fix PDF ToUnicode CMAP for ligatures
Move the glyph to character(s) mapping to CommonSalLayout where we have enough information to do this properly. This correctly handles ligatures at end of run that wasn’t handled before, and also fixes a bug in the PDF writer code when there is more than one ligature in the run (it forgot to clear aCodeUnitsPerGlyph vector after each iteration). Also drop the “temporary” fix for rotated glyph from 2009 that does not seem to be needed now (the document from that bug exports correctly after this change). Change-Id: I5b5b1f4470bbd0ef05cbbc86dfa29d2ff51249ea Reviewed-on: https://gerrit.libreoffice.org/51617 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> (cherry picked from commit b94a66ebc8db6c5ca9c7dcfdfbb06b49deae4939) Reviewed-on: https://gerrit.libreoffice.org/51715
Diffstat (limited to 'vcl/source')
-rw-r--r--vcl/source/gdi/CommonSalLayout.cxx45
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx48
2 files changed, 56 insertions, 37 deletions
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 2f110b138a8a..cfd86ed27409 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -690,6 +690,49 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
for (int i = 0; i < nRunGlyphCount; ++i) {
int32_t nGlyphIndex = pHbGlyphInfos[i].codepoint;
int32_t nCharPos = pHbGlyphInfos[i].cluster;
+ int32_t nCharCount = 0;
+
+ // Find the number of characters that make up this glyph.
+ if (!bRightToLeft)
+ {
+ // If the cluster is the same as previous glyph, then this
+ // already consumed, skip.
+ if (i > 0 && pHbGlyphInfos[i].cluster == pHbGlyphInfos[i - 1].cluster)
+ nCharCount = 0;
+ else
+ {
+ // Find the next glyph with a different cluster, or the
+ // end of text.
+ int j = i;
+ int32_t nNextCharPos = nCharPos;
+ while (nNextCharPos == nCharPos && j < nRunGlyphCount)
+ nNextCharPos = pHbGlyphInfos[j++].cluster;
+
+ if (nNextCharPos == nCharPos)
+ nNextCharPos = rArgs.mnEndCharPos;
+ nCharCount = nNextCharPos - nCharPos;
+ }
+ }
+ else
+ {
+ // If the cluster is the same as previous glyph, then this
+ // will be consumed later, skip.
+ if (i < nRunGlyphCount - 1 && pHbGlyphInfos[i].cluster == pHbGlyphInfos[i + 1].cluster)
+ nCharCount = 0;
+ else
+ {
+ // Find the previous glyph with a different cluster, or
+ // the end of text.
+ int j = i;
+ int32_t nNextCharPos = nCharPos;
+ while (nNextCharPos == nCharPos && j >= 0)
+ nNextCharPos = pHbGlyphInfos[j--].cluster;
+
+ if (nNextCharPos == nCharPos)
+ nNextCharPos = rArgs.mnEndCharPos;
+ nCharCount = nNextCharPos - nCharPos;
+ }
+ }
// if needed request glyph fallback by updating LayoutArgs
if (!nGlyphIndex)
@@ -756,7 +799,7 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
nYOffset = std::lround(nYOffset * nYScale);
Point aNewPos(aCurrPos.X() + nXOffset, aCurrPos.Y() + nYOffset);
- const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags,
+ const GlyphItem aGI(nCharPos, nCharCount, nGlyphIndex, aNewPos, nGlyphFlags,
nAdvance, nXOffset);
AppendGlyph(aGI);
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 03b1a1d9e12d..58711a9d862b 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6598,7 +6598,6 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
bool bVertical = m_aCurrentPDFState.m_aFont.IsVertical();
int nGlyphs;
int nIndex = 0;
- int nMaxCharPos = rText.getLength()-1;
double fXScale = 1.0;
double fSkew = 0.0;
sal_Int32 nPixelFontHeight = m_pReferenceDevice->mpFontInstance->maFontSelData.mnHeight;
@@ -6717,48 +6716,25 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
FontMetric aRefDevFontMetric = m_pReferenceDevice->GetFontMetric();
// collect the glyphs into a single array
- const int nTmpMaxGlyphs = rLayout.GetOrientation() ? 1 : nMaxGlyphs; // #i97991# temporary workaround for #i87686#
std::vector< PDFGlyph > aGlyphs;
- aGlyphs.reserve( nTmpMaxGlyphs );
+ aGlyphs.reserve( nMaxGlyphs );
// first get all the glyphs and register them; coordinates still in Pixel
Point aGNGlyphPos;
- while ((nGlyphs = rLayout.GetNextGlyphs(nTmpMaxGlyphs, pGlyphs, aGNGlyphPos, nIndex, pFallbackFonts)) != 0)
+ while ((nGlyphs = rLayout.GetNextGlyphs(nMaxGlyphs, pGlyphs, aGNGlyphPos, nIndex, pFallbackFonts)) != 0)
{
aCodeUnits.clear();
+ aCodeUnitsPerGlyph.clear();
for( int i = 0; i < nGlyphs; i++ )
{
- // default case: 1 glyph is one unicode
- aCodeUnitsPerGlyph.push_back(1);
- if (pGlyphs[i]->mnCharPos >= 0 && pGlyphs[i]->mnCharPos <= nMaxCharPos)
- {
- int nChars = 1;
- // try to handle ligatures and such
- if( i < nGlyphs-1 )
- {
- nChars = pGlyphs[i+1]->mnCharPos - pGlyphs[i]->mnCharPos;
- int start = pGlyphs[i]->mnCharPos;
- // #i115618# fix for simple RTL+CTL cases
- // supports RTL ligatures. TODO: more complex CTL, etc.
- if( nChars < 0 )
- {
- nChars = -nChars;
- start = pGlyphs[i+1]->mnCharPos + 1;
- }
- else if (nChars == 0)
- nChars = 1;
- aCodeUnitsPerGlyph.back() = nChars;
- for( int n = 0; n < nChars; n++ )
- aCodeUnits.push_back( rText[ start + n ] );
- }
- else
- aCodeUnits.push_back(rText[pGlyphs[i]->mnCharPos]);
- }
- else
- aCodeUnits.push_back( 0 );
- // note: in case of ctl one character may result
- // in multiple glyphs. The current SalLayout
- // implementations set -1 then to indicate that no direct
- // mapping is possible
+ // try to handle ligatures and such
+ int nStart = pGlyphs[i]->mnCharPos;
+ int nChars = pGlyphs[i]->mnCharCount;
+ if (nChars < 0)
+ nChars = 0;
+
+ aCodeUnitsPerGlyph.push_back(nChars);
+ for( int n = 0; n < nChars; n++ )
+ aCodeUnits.push_back( rText[ nStart + n ] );
}
registerGlyphs( nGlyphs, pGlyphs, pGlyphWidths, aCodeUnits.data(), aCodeUnitsPerGlyph.data(), pMappedGlyphs, pMappedFontObjects, pFallbackFonts );