nss: upgrade to release 3.73
[LibreOffice.git] / vcl / qa / cppunit / complextext.cxx
blobf8d417e183506a214586a1d89cfc94240a7a83b0
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>
14 #include <tools/long.hxx>
16 #if HAVE_MORE_FONTS
17 // must be declared before inclusion of test/bootstrapfixture.hxx
18 static std::ostream& operator<<(std::ostream& rStream, const std::vector<tools::Long>& rVec);
19 #endif
20 #include <test/bootstrapfixture.hxx>
22 #include <vcl/wrkwin.hxx>
23 #include <vcl/virdev.hxx>
24 // workaround MSVC2015 issue with std::unique_ptr
25 #include <sallayout.hxx>
26 #include <salgdi.hxx>
28 #if HAVE_MORE_FONTS
29 static std::ostream& operator<<(std::ostream& rStream, const std::vector<tools::Long>& rVec)
31 rStream << "{ ";
32 for (size_t i = 0; i < rVec.size() - 1; i++)
33 rStream << rVec[i] << ", ";
34 rStream << rVec.back();
35 rStream << " }";
36 return rStream;
38 #endif
40 class VclComplexTextTest : public test::BootstrapFixture
42 public:
43 VclComplexTextTest() : BootstrapFixture(true, false) {}
45 /// Play with font measuring etc.
46 void testArabic();
47 void testKashida();
48 void testTdf95650(); // Windows-only issue
50 CPPUNIT_TEST_SUITE(VclComplexTextTest);
51 CPPUNIT_TEST(testArabic);
52 CPPUNIT_TEST(testKashida);
53 CPPUNIT_TEST(testTdf95650);
54 CPPUNIT_TEST_SUITE_END();
57 void VclComplexTextTest::testArabic()
59 #if HAVE_MORE_FONTS
60 const unsigned char pOneTwoThreeUTF8[] = {
61 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xad, 0xd9, 0x90,
62 0xd8, 0xaf, 0xd9, 0x92, 0x20, 0xd8, 0xa5, 0xd8,
63 0xab, 0xd9, 0x8d, 0xd9, 0x86, 0xd9, 0x8a, 0xd9,
64 0x86, 0x20, 0xd8, 0xab, 0xd9, 0x84, 0xd8, 0xa7,
65 0xd8, 0xab, 0xd8, 0xa9, 0xd9, 0x8c, 0x00
67 OUString aOneTwoThree( reinterpret_cast<char const *>(pOneTwoThreeUTF8),
68 SAL_N_ELEMENTS( pOneTwoThreeUTF8 ) - 1,
69 RTL_TEXTENCODING_UTF8 );
70 ScopedVclPtrInstance<WorkWindow> pWin(static_cast<vcl::Window *>(nullptr));
71 CPPUNIT_ASSERT( pWin );
73 vcl::Font aFont("DejaVu Sans", "Book", Size(0, 12));
75 OutputDevice *pOutDev = pWin.get();
76 pOutDev->SetFont( aFont );
78 // absolute character widths AKA text array.
79 std::vector<tools::Long> aRefCharWidths {6, 9, 16, 16, 22, 22, 26, 29, 32, 32,
80 36, 40, 49, 53, 56, 63, 63, 66, 72, 72};
81 std::vector<tools::Long> aCharWidths(aOneTwoThree.getLength(), 0);
82 tools::Long nTextWidth = pOutDev->GetTextArray(aOneTwoThree, aCharWidths.data());
84 CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
85 // this sporadically returns 75 or 74 on some of the windows tinderboxes eg. tb73
86 CPPUNIT_ASSERT_EQUAL(tools::Long(72), nTextWidth);
87 CPPUNIT_ASSERT_EQUAL(nTextWidth, aCharWidths.back());
89 // text advance width and line height
90 CPPUNIT_ASSERT_EQUAL(tools::Long(72), pOutDev->GetTextWidth(aOneTwoThree));
91 CPPUNIT_ASSERT_EQUAL(tools::Long(14), pOutDev->GetTextHeight());
93 // exact bounding rectangle, not essentially the same as text width/height
94 tools::Rectangle aBoundRect;
95 pOutDev->GetTextBoundRect(aBoundRect, aOneTwoThree);
96 CPPUNIT_ASSERT_DOUBLES_EQUAL(0, aBoundRect.getX(), 1); // This sometimes equals to 1
97 CPPUNIT_ASSERT_DOUBLES_EQUAL(1, aBoundRect.getY(), 1);
98 CPPUNIT_ASSERT_DOUBLES_EQUAL(71, aBoundRect.getWidth(), 1); // This sometimes equals to 70
99 CPPUNIT_ASSERT_DOUBLES_EQUAL(15, aBoundRect.getHeight(), 1);
101 #if 0
102 // FIXME: This seems to be wishful thinking, GetTextRect() does not take
103 // rotation into account.
105 // normal orientation
106 tools::Rectangle aInput;
107 tools::Rectangle aRect = pOutDev->GetTextRect( aInput, aOneTwoThree );
109 // now rotate 270 degrees
110 vcl::Font aRotated( aFont );
111 aRotated.SetOrientation( 2700 );
112 pOutDev->SetFont( aRotated );
113 tools::Rectangle aRectRot = pOutDev->GetTextRect( aInput, aOneTwoThree );
115 // Check that we did do the rotation...
116 fprintf( stderr, "%" SAL_PRIdINT64 " %" SAL_PRIdINT64 " %" SAL_PRIdINT64 " %" SAL_PRIdINT64 "\n",
117 sal_Int64(aRect.GetWidth()), sal_Int64(aRect.GetHeight()),
118 sal-Int64(aRectRot.GetWidth()), sal_Int64(aRectRot.GetHeight()) );
119 CPPUNIT_ASSERT( aRectRot.GetWidth() == aRect.GetHeight() );
120 CPPUNIT_ASSERT( aRectRot.GetHeight() == aRect.GetWidth() );
121 #endif
122 #endif
125 void VclComplexTextTest::testKashida()
127 #if HAVE_MORE_FONTS
128 // Cache the glyph list of some Arabic text.
129 ScopedVclPtrInstance<VirtualDevice> pOutputDevice;
130 auto aText
131 = OUString::fromUtf8(u8"ﻊﻨﺻﺭ ﺎﻠﻓﻮﺴﻓﻭﺭ ﻊﻨﺻﺭ ﻒﻟﺰﻳ ﺺﻠﺑ. ﺖﺘﻛﻮﻧ ﺎﻟﺩﻭﺭﺓ ﺎﻟﺭﺎﺒﻋﺓ ﻢﻧ ١٥ ﻊﻨﺻﺭﺍ.");
132 std::unique_ptr<SalLayout> pLayout = pOutputDevice->ImplLayout(
133 aText, 0, aText.getLength(), Point(0, 0), 0, nullptr, SalLayoutFlags::GlyphItemsOnly);
134 const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs();
135 if (!pGlyphs)
136 // Failed in some non-interesting ways.
137 return;
138 SalLayoutGlyphs aGlyphs = *pGlyphs;
140 // Now lay it out using the cached glyph list.
141 ImplLayoutArgs aLayoutArgs(aText, 0, aText.getLength(), SalLayoutFlags::NONE,
142 pOutputDevice->GetFont().GetLanguageTag(), nullptr);
143 pLayout = pOutputDevice->GetGraphics()->GetTextLayout(0);
144 CPPUNIT_ASSERT(pLayout->LayoutText(aLayoutArgs, &aGlyphs));
146 // Without the accompanying fix in place, this test would have failed with 'assertion failed'.
147 // The kashida justification flag was lost when going via the glyph cache.
148 CPPUNIT_ASSERT(aLayoutArgs.mnFlags & SalLayoutFlags::KashidaJustification);
149 #endif
152 void VclComplexTextTest::testTdf95650()
154 const sal_Unicode pTxt[] = {
155 0x0131, 0x0302, 0x0504, 0x4E44, 0x3031, 0x3030, 0x3531, 0x2D30,
156 0x3037, 0x0706, 0x0908, 0x0B0A, 0x0D0C, 0x0F0E, 0x072E, 0x100A,
157 0x0D11, 0x1312, 0x0105, 0x020A, 0x0512, 0x1403, 0x030C, 0x1528,
158 0x2931, 0x632E, 0x7074, 0x0D20, 0x0E0A, 0x100A, 0xF00D, 0x0D20,
159 0x030A, 0x0C0B, 0x20E0, 0x0A0D
161 OUString aTxt(pTxt, SAL_N_ELEMENTS(pTxt) - 1);
162 ScopedVclPtrInstance<WorkWindow> pWin(static_cast<vcl::Window *>(nullptr));
163 CPPUNIT_ASSERT(pWin);
165 OutputDevice *pOutDev = pWin.get();
166 // Check that the following executes without failing assertion
167 pOutDev->ImplLayout(aTxt, 9, 1, Point(), 0, nullptr, SalLayoutFlags::BiDiRtl);
170 CPPUNIT_TEST_SUITE_REGISTRATION(VclComplexTextTest);
172 CPPUNIT_PLUGIN_IMPLEMENT();
174 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */