Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / qa / cppunit / complextext.cxx
blobd3cdc230c0bc3c0f7583df77c8f5f14d2f278e36
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <config_features.h>
12 #include <ostream>
13 #include <vector>
15 #if HAVE_MORE_FONTS
16 // must be declared before inclusion of test/bootstrapfixture.hxx
17 static std::ostream& operator<<(std::ostream& rStream, const std::vector<long>& rVec);
18 #endif
19 #include <test/bootstrapfixture.hxx>
21 #include <vcl/wrkwin.hxx>
22 #include <vcl/virdev.hxx>
23 // workaround MSVC2015 issue with std::unique_ptr
24 #include <sallayout.hxx>
25 #include <salgdi.hxx>
27 #if HAVE_MORE_FONTS
28 static std::ostream& operator<<(std::ostream& rStream, const std::vector<long>& rVec)
30 rStream << "{ ";
31 for (size_t i = 0; i < rVec.size() - 1; i++)
32 rStream << rVec[i] << ", ";
33 rStream << rVec.back();
34 rStream << " }";
35 return rStream;
37 #endif
39 class VclComplexTextTest : public test::BootstrapFixture
41 public:
42 VclComplexTextTest() : BootstrapFixture(true, false) {}
44 /// Play with font measuring etc.
45 void testArabic();
46 void testKashida();
47 void testTdf95650(); // Windows-only issue
49 CPPUNIT_TEST_SUITE(VclComplexTextTest);
50 CPPUNIT_TEST(testArabic);
51 CPPUNIT_TEST(testKashida);
52 CPPUNIT_TEST(testTdf95650);
53 CPPUNIT_TEST_SUITE_END();
56 void VclComplexTextTest::testArabic()
58 #if HAVE_MORE_FONTS
59 const unsigned char pOneTwoThreeUTF8[] = {
60 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xad, 0xd9, 0x90,
61 0xd8, 0xaf, 0xd9, 0x92, 0x20, 0xd8, 0xa5, 0xd8,
62 0xab, 0xd9, 0x8d, 0xd9, 0x86, 0xd9, 0x8a, 0xd9,
63 0x86, 0x20, 0xd8, 0xab, 0xd9, 0x84, 0xd8, 0xa7,
64 0xd8, 0xab, 0xd8, 0xa9, 0xd9, 0x8c, 0x00
66 OUString aOneTwoThree( reinterpret_cast<char const *>(pOneTwoThreeUTF8),
67 SAL_N_ELEMENTS( pOneTwoThreeUTF8 ) - 1,
68 RTL_TEXTENCODING_UTF8 );
69 ScopedVclPtrInstance<WorkWindow> pWin(static_cast<vcl::Window *>(nullptr));
70 CPPUNIT_ASSERT( pWin );
72 vcl::Font aFont("DejaVu Sans", "Book", Size(0, 12));
74 OutputDevice *pOutDev = pWin.get();
75 pOutDev->SetFont( aFont );
77 // absolute character widths AKA text array.
78 std::vector<long> aRefCharWidths {6, 9, 16, 16, 22, 22, 26, 29, 32, 32,
79 36, 40, 49, 53, 56, 63, 63, 66, 72, 72};
80 std::vector<long> aCharWidths(aOneTwoThree.getLength(), 0);
81 long nTextWidth = pOutDev->GetTextArray(aOneTwoThree, aCharWidths.data());
83 CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
84 // this sporadically returns 75 or 74 on some of the windows tinderboxes eg. tb73
85 CPPUNIT_ASSERT_EQUAL(72L, nTextWidth);
86 CPPUNIT_ASSERT_EQUAL(nTextWidth, aCharWidths.back());
88 // text advance width and line height
89 CPPUNIT_ASSERT_EQUAL(72L, pOutDev->GetTextWidth(aOneTwoThree));
90 CPPUNIT_ASSERT_EQUAL(14L, pOutDev->GetTextHeight());
92 // exact bounding rectangle, not essentially the same as text width/height
93 tools::Rectangle aBoundRect, aTestRect( 0, 1, 71, 15 );
94 pOutDev->GetTextBoundRect(aBoundRect, aOneTwoThree);
95 CPPUNIT_ASSERT_EQUAL(aTestRect, aBoundRect);
97 #if 0
98 // FIXME: This seems to be wishful thinking, GetTextRect() does not take
99 // rotation into account.
101 // normal orientation
102 tools::Rectangle aInput;
103 tools::Rectangle aRect = pOutDev->GetTextRect( aInput, aOneTwoThree );
105 // now rotate 270 degress
106 vcl::Font aRotated( aFont );
107 aRotated.SetOrientation( 2700 );
108 pOutDev->SetFont( aRotated );
109 tools::Rectangle aRectRot = pOutDev->GetTextRect( aInput, aOneTwoThree );
111 // Check that we did do the rotation ...
112 fprintf( stderr, "%ld %ld %ld %ld\n",
113 aRect.GetWidth(), aRect.GetHeight(),
114 aRectRot.GetWidth(), aRectRot.GetHeight() );
115 CPPUNIT_ASSERT( aRectRot.GetWidth() == aRect.GetHeight() );
116 CPPUNIT_ASSERT( aRectRot.GetHeight() == aRect.GetWidth() );
117 #endif
118 #endif
121 void VclComplexTextTest::testKashida()
123 #if HAVE_MORE_FONTS
124 // Cache the glyph list of some Arabic text.
125 ScopedVclPtrInstance<VirtualDevice> pOutputDevice;
126 auto aText
127 = OUString::fromUtf8(u8"ﻊﻨﺻﺭ ﺎﻠﻓﻮﺴﻓﻭﺭ ﻊﻨﺻﺭ ﻒﻟﺰﻳ ﺺﻠﺑ. ﺖﺘﻛﻮﻧ ﺎﻟﺩﻭﺭﺓ ﺎﻟﺭﺎﺒﻋﺓ ﻢﻧ ١٥ ﻊﻨﺻﺭﺍ.");
128 std::unique_ptr<SalLayout> pLayout = pOutputDevice->ImplLayout(
129 aText, 0, aText.getLength(), Point(0, 0), 0, nullptr, SalLayoutFlags::GlyphItemsOnly);
130 const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs();
131 if (!pGlyphs)
132 // Failed in some non-interesting ways.
133 return;
134 SalLayoutGlyphs aGlyphs = *pGlyphs;
136 // Now lay it out using the cached glyph list.
137 ImplLayoutArgs aLayoutArgs(aText, 0, aText.getLength(), SalLayoutFlags::NONE,
138 pOutputDevice->GetFont().GetLanguageTag(), nullptr);
139 pLayout = pOutputDevice->GetGraphics()->GetTextLayout(0);
140 CPPUNIT_ASSERT(pLayout->LayoutText(aLayoutArgs, &aGlyphs));
142 // Without the accompanying fix in place, this test would have failed with 'assertion failed'.
143 // The kashida justification flag was lost when going via the glyph cache.
144 CPPUNIT_ASSERT(aLayoutArgs.mnFlags & SalLayoutFlags::KashidaJustification);
145 #endif
148 void VclComplexTextTest::testTdf95650()
150 const sal_Unicode pTxt[] = {
151 0x0131, 0x0302, 0x0504, 0x4E44, 0x3031, 0x3030, 0x3531, 0x2D30,
152 0x3037, 0x0706, 0x0908, 0x0B0A, 0x0D0C, 0x0F0E, 0x072E, 0x100A,
153 0x0D11, 0x1312, 0x0105, 0x020A, 0x0512, 0x1403, 0x030C, 0x1528,
154 0x2931, 0x632E, 0x7074, 0x0D20, 0x0E0A, 0x100A, 0xF00D, 0x0D20,
155 0x030A, 0x0C0B, 0x20E0, 0x0A0D
157 OUString aTxt(pTxt, SAL_N_ELEMENTS(pTxt) - 1);
158 ScopedVclPtrInstance<WorkWindow> pWin(static_cast<vcl::Window *>(nullptr));
159 CPPUNIT_ASSERT(pWin);
161 OutputDevice *pOutDev = pWin.get();
162 // Check that the following executes without failing assertion
163 pOutDev->ImplLayout(aTxt, 9, 1, Point(), 0, nullptr, SalLayoutFlags::BiDiRtl);
166 CPPUNIT_TEST_SUITE_REGISTRATION(VclComplexTextTest);
168 CPPUNIT_PLUGIN_IMPLEMENT();
170 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */