Kaydet (Commit) 8308d6a3 authored tarafından Miklos Vajna's avatar Miklos Vajna

Related: tdf#124109 vcl: make glyph item caching work with kashida glyphs

This was broken because GenericSalLayout::LayoutText() sets the
SalLayoutFlags::KashidaJustification flag as a side-effect of building
the glyph list. So in case we cache the list and not build it, the flag
will be missing. This means that later in
GenericSalLayout::ApplyDXArray() kashida glyphs won't be inserted.

With this, the workaround in sw can be removed.

Change-Id: Ic18211bf50ca673daa238e8950a381915e4b3096
Reviewed-on: https://gerrit.libreoffice.org/69566Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
üst a05a55dd
...@@ -1492,7 +1492,6 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) ...@@ -1492,7 +1492,6 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
long nSpaceAdd = rInf.GetSpace() / SPACING_PRECISION_FACTOR; long nSpaceAdd = rInf.GetSpace() / SPACING_PRECISION_FACTOR;
bool bNoHalfSpace = false; bool bNoHalfSpace = false;
bool bCacheLayout = true;
if ( rInf.GetFont() && rInf.GetLen() ) if ( rInf.GetFont() && rInf.GetLen() )
{ {
...@@ -1535,12 +1534,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) ...@@ -1535,12 +1534,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
if ( pSI && pSI->CountKashida() && if ( pSI && pSI->CountKashida() &&
pSI->KashidaJustify( pKernArray.get(), pScrArray.get(), rInf.GetIdx(), pSI->KashidaJustify( pKernArray.get(), pScrArray.get(), rInf.GetIdx(),
rInf.GetLen(), nSpaceAdd ) != -1 ) rInf.GetLen(), nSpaceAdd ) != -1 )
{
nSpaceAdd = 0; nSpaceAdd = 0;
// Layout can't be reused in this case, it would lead to missing gaps in
// place of kashida.
bCacheLayout = false;
}
else else
bNoHalfSpace = true; bNoHalfSpace = true;
} }
...@@ -1821,10 +1815,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) ...@@ -1821,10 +1815,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
? (rInf.GetIdx() ? 1 : 0) ? (rInf.GetIdx() ? 1 : 0)
: sal_Int32(rInf.GetIdx()); : sal_Int32(rInf.GetIdx());
aGlyphsKey = SwTextGlyphsKey{ &rInf.GetOut(), *pStr, nTmpIdx, nLen }; aGlyphsKey = SwTextGlyphsKey{ &rInf.GetOut(), *pStr, nTmpIdx, nLen };
if (bCacheLayout)
pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]); pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]);
else
pGlyphs = nullptr;
rInf.GetOut().DrawTextArray( aTextOriginPos, *pStr, pKernArray.get(), rInf.GetOut().DrawTextArray( aTextOriginPos, *pStr, pKernArray.get(),
nTmpIdx , nLen, SalLayoutFlags::NONE, pGlyphs ); nTmpIdx , nLen, SalLayoutFlags::NONE, pGlyphs );
if (bBullet) if (bBullet)
......
...@@ -28,6 +28,7 @@ $(eval $(call gb_CppunitTest_use_libraries,vcl_complextext, \ ...@@ -28,6 +28,7 @@ $(eval $(call gb_CppunitTest_use_libraries,vcl_complextext, \
comphelper \ comphelper \
cppu \ cppu \
cppuhelper \ cppuhelper \
i18nlangtag \
sal \ sal \
svt \ svt \
test \ test \
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <tools/gen.hxx> #include <tools/gen.hxx>
#include <vcl/dllapi.h> #include <vcl/dllapi.h>
#include <vcl/glyphitem.hxx> #include <vcl/glyphitem.hxx>
#include <vcl/outdev.hxx>
#include <vector> #include <vector>
#include "fontinstance.hxx" #include "fontinstance.hxx"
...@@ -103,6 +104,7 @@ public: ...@@ -103,6 +104,7 @@ public:
private: private:
mutable rtl::Reference<LogicalFontInstance> m_rFontInstance; mutable rtl::Reference<LogicalFontInstance> m_rFontInstance;
SalLayoutFlags mnFlags = SalLayoutFlags::NONE;
SalLayoutGlyphsImpl(SalLayoutGlyphs& rGlyphs, LogicalFontInstance& rFontInstance) SalLayoutGlyphsImpl(SalLayoutGlyphs& rGlyphs, LogicalFontInstance& rFontInstance)
: m_rFontInstance(&rFontInstance) : m_rFontInstance(&rFontInstance)
......
...@@ -73,7 +73,7 @@ public: ...@@ -73,7 +73,7 @@ public:
bool PosIsInAnyRun( int nCharPos ) const; bool PosIsInAnyRun( int nCharPos ) const;
}; };
class ImplLayoutArgs class VCL_DLLPUBLIC ImplLayoutArgs
{ {
public: public:
// string related inputs // string related inputs
...@@ -158,7 +158,7 @@ private: ...@@ -158,7 +158,7 @@ private:
bool mbIncomplete; bool mbIncomplete;
}; };
class VCL_PLUGIN_PUBLIC GenericSalLayout : public SalLayout class VCL_DLLPUBLIC GenericSalLayout : public SalLayout
{ {
friend void MultiSalLayout::AdjustLayout(ImplLayoutArgs&); friend void MultiSalLayout::AdjustLayout(ImplLayoutArgs&);
......
...@@ -19,8 +19,10 @@ static std::ostream& operator<<(std::ostream& rStream, const std::vector<long>& ...@@ -19,8 +19,10 @@ static std::ostream& operator<<(std::ostream& rStream, const std::vector<long>&
#include <test/bootstrapfixture.hxx> #include <test/bootstrapfixture.hxx>
#include <vcl/wrkwin.hxx> #include <vcl/wrkwin.hxx>
#include <vcl/virdev.hxx>
// workaround MSVC2015 issue with std::unique_ptr // workaround MSVC2015 issue with std::unique_ptr
#include <sallayout.hxx> #include <sallayout.hxx>
#include <salgdi.hxx>
#include <osl/file.hxx> #include <osl/file.hxx>
#include <osl/process.h> #include <osl/process.h>
...@@ -45,6 +47,7 @@ public: ...@@ -45,6 +47,7 @@ public:
#if HAVE_MORE_FONTS #if HAVE_MORE_FONTS
/// Play with font measuring etc. /// Play with font measuring etc.
void testArabic(); void testArabic();
void testKashida();
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
void testTdf95650(); // Windows-only issue void testTdf95650(); // Windows-only issue
...@@ -53,6 +56,7 @@ public: ...@@ -53,6 +56,7 @@ public:
CPPUNIT_TEST_SUITE(VclComplexTextTest); CPPUNIT_TEST_SUITE(VclComplexTextTest);
#if HAVE_MORE_FONTS #if HAVE_MORE_FONTS
CPPUNIT_TEST(testArabic); CPPUNIT_TEST(testArabic);
CPPUNIT_TEST(testKashida);
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
CPPUNIT_TEST(testTdf95650); CPPUNIT_TEST(testTdf95650);
...@@ -136,6 +140,29 @@ void VclComplexTextTest::testArabic() ...@@ -136,6 +140,29 @@ void VclComplexTextTest::testArabic()
(void)aRect; (void)aRectRot; (void)aRect; (void)aRectRot;
#endif #endif
} }
void VclComplexTextTest::testKashida()
{
// Cache the glyph list of some Arabic text.
ScopedVclPtrInstance<VirtualDevice> pOutputDevice;
auto aText
= OUString::fromUtf8(u8"ﻊﻨﺻﺭ ﺎﻠﻓﻮﺴﻓﻭﺭ ﻊﻨﺻﺭ ﻒﻟﺰﻳ ﺺﻠﺑ. ﺖﺘﻛﻮﻧ ﺎﻟﺩﻭﺭﺓ ﺎﻟﺭﺎﺒﻋﺓ ﻢﻧ ١٥ ﻊﻨﺻﺭﺍ.");
std::unique_ptr<SalLayout> pLayout = pOutputDevice->ImplLayout(
aText, 0, aText.getLength(), Point(0, 0), 0, nullptr, SalLayoutFlags::GlyphItemsOnly);
const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs();
CPPUNIT_ASSERT(pGlyphs);
SalLayoutGlyphs aGlyphs = *pGlyphs;
// Now lay it out using the cached glyph list.
ImplLayoutArgs aLayoutArgs(aText, 0, aText.getLength(), SalLayoutFlags::NONE,
pOutputDevice->GetFont().GetLanguageTag(), nullptr);
pLayout = pOutputDevice->GetGraphics()->GetTextLayout(0);
CPPUNIT_ASSERT(pLayout->LayoutText(aLayoutArgs, &aGlyphs));
// Without the accompanying fix in place, this test would have failed with 'assertion failed'.
// The kashida justification flag was lost when going via the glyph cache.
CPPUNIT_ASSERT(aLayoutArgs.mnFlags & SalLayoutFlags::KashidaJustification);
}
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
......
...@@ -273,6 +273,8 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs* ...@@ -273,6 +273,8 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs*
{ {
// Work with pre-computed glyph items. // Work with pre-computed glyph items.
m_GlyphItems = *pGlyphs; m_GlyphItems = *pGlyphs;
// Some flags are set as a side effect of text layout, restore them here.
rArgs.mnFlags |= pGlyphs->Impl()->mnFlags;
return true; return true;
} }
...@@ -580,6 +582,10 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs* ...@@ -580,6 +582,10 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs*
hb_buffer_destroy(pHbBuffer); hb_buffer_destroy(pHbBuffer);
// Some flags are set as a side effect of text layout, save them here.
if (rArgs.mnFlags & SalLayoutFlags::GlyphItemsOnly)
m_GlyphItems.Impl()->mnFlags = rArgs.mnFlags;
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment