summaryrefslogtreecommitdiffstats
path: root/gfx/tests/gtest/gfxFontSelectionTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/tests/gtest/gfxFontSelectionTest.cpp')
-rw-r--r--gfx/tests/gtest/gfxFontSelectionTest.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/gfx/tests/gtest/gfxFontSelectionTest.cpp b/gfx/tests/gtest/gfxFontSelectionTest.cpp
new file mode 100644
index 000000000..f00aa9e9e
--- /dev/null
+++ b/gfx/tests/gtest/gfxFontSelectionTest.cpp
@@ -0,0 +1,320 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
+#include "nsCOMPtr.h"
+#include "nsTArray.h"
+#include "nsString.h"
+#include "nsDependentString.h"
+
+#include "mozilla/Preferences.h"
+
+#include "gfxContext.h"
+#include "gfxFont.h"
+#include "gfxPlatform.h"
+
+#include "gfxFontTest.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+
+enum {
+ S_UTF8 = 0,
+ S_ASCII = 1
+};
+
+class FrameTextRunCache;
+
+struct LiteralArray {
+ LiteralArray (unsigned long l1) {
+ data.AppendElement(l1);
+ }
+ LiteralArray (unsigned long l1, unsigned long l2) {
+ data.AppendElement(l1);
+ data.AppendElement(l2);
+ }
+ LiteralArray (unsigned long l1, unsigned long l2, unsigned long l3) {
+ data.AppendElement(l1);
+ data.AppendElement(l2);
+ data.AppendElement(l3);
+ }
+ LiteralArray (unsigned long l1, unsigned long l2, unsigned long l3, unsigned long l4) {
+ data.AppendElement(l1);
+ data.AppendElement(l2);
+ data.AppendElement(l3);
+ data.AppendElement(l4);
+ }
+ LiteralArray (unsigned long l1, unsigned long l2, unsigned long l3, unsigned long l4, unsigned long l5) {
+ data.AppendElement(l1);
+ data.AppendElement(l2);
+ data.AppendElement(l3);
+ data.AppendElement(l4);
+ data.AppendElement(l5);
+ }
+
+ LiteralArray (const LiteralArray& other) {
+ data = other.data;
+ }
+
+ nsTArray<unsigned long> data;
+};
+
+#define GLYPHS LiteralArray
+
+struct TestEntry {
+ TestEntry (const char *aUTF8FamilyString,
+ const gfxFontStyle& aFontStyle,
+ const char *aString)
+ : utf8FamilyString(aUTF8FamilyString),
+ fontStyle(aFontStyle),
+ stringType(S_ASCII),
+ string(aString),
+ isRTL(false)
+ {
+ }
+
+ TestEntry (const char *aUTF8FamilyString,
+ const gfxFontStyle& aFontStyle,
+ int stringType,
+ const char *aString)
+ : utf8FamilyString(aUTF8FamilyString),
+ fontStyle(aFontStyle),
+ stringType(stringType),
+ string(aString),
+ isRTL(false)
+ {
+ }
+
+ struct ExpectItem {
+ ExpectItem(const nsCString& aFontName,
+ const LiteralArray& aGlyphs)
+ : fontName(aFontName), glyphs(aGlyphs)
+ { }
+
+ bool Compare(const nsCString& aFontName,
+ cairo_glyph_t *aGlyphs,
+ int num_glyphs)
+ {
+ // bit that allowed for empty fontname to match all is commented
+ // out
+ if (/*!fontName.IsEmpty() &&*/ !fontName.Equals(aFontName))
+ return false;
+
+ if (num_glyphs != int(glyphs.data.Length()))
+ return false;
+
+ for (int j = 0; j < num_glyphs; j++) {
+ if (glyphs.data[j] != aGlyphs[j].index)
+ return false;
+ }
+
+ return true;
+ }
+
+ nsCString fontName;
+ LiteralArray glyphs;
+ };
+
+ void SetRTL()
+ {
+ isRTL = true;
+ }
+
+ // Empty/nullptr fontName means ignore font name
+ void Expect (const char *platform,
+ const char *fontName,
+ const LiteralArray& glyphs)
+ {
+ if (fontName)
+ Expect (platform, nsDependentCString(fontName), glyphs);
+ else
+ Expect (platform, nsCString(), glyphs);
+ }
+
+ void Expect (const char *platform,
+ const nsCString& fontName,
+ const LiteralArray& glyphs)
+ {
+#if defined(XP_WIN)
+ if (strcmp(platform, "win32"))
+ return;
+#elif defined(XP_MACOSX)
+ if (strcmp(platform, "macosx"))
+ return;
+#elif defined(XP_UNIX)
+ if (strcmp(platform, "gtk2-pango"))
+ return;
+#else
+ return;
+#endif
+
+ expectItems.AppendElement(ExpectItem(fontName, glyphs));
+ }
+
+ bool Check (gfxFontTestStore *store) {
+ if (expectItems.Length() == 0 ||
+ store->items.Length() != expectItems.Length())
+ {
+ return false;
+ }
+
+ for (uint32_t i = 0; i < expectItems.Length(); i++) {
+ if (!expectItems[i].Compare(store->items[i].platformFont,
+ store->items[i].glyphs,
+ store->items[i].num_glyphs))
+ return false;
+ }
+
+ return true;
+ }
+
+ const char *utf8FamilyString;
+ gfxFontStyle fontStyle;
+
+ int stringType;
+ const char *string;
+ bool isRTL;
+
+ nsTArray<ExpectItem> expectItems;
+};
+
+static already_AddRefed<gfxContext>
+MakeContext ()
+{
+ const int size = 200;
+
+ RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
+ CreateOffscreenContentDrawTarget(IntSize(size, size),
+ SurfaceFormat::B8G8R8X8);
+ RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(drawTarget);
+ if (!ctx) {
+ MOZ_CRASH("gfxContext creation failed");
+ }
+
+ return ctx.forget();
+}
+
+TestEntry*
+AddTest (nsTArray<TestEntry>& testList,
+ const char *utf8FamilyString,
+ const gfxFontStyle& fontStyle,
+ int stringType,
+ const char *string)
+{
+ TestEntry te (utf8FamilyString,
+ fontStyle,
+ stringType,
+ string);
+
+ testList.AppendElement(te);
+
+ return &(testList[testList.Length()-1]);
+}
+
+void
+DumpStore (gfxFontTestStore *store) {
+ if (store->items.Length() == 0) {
+ printf ("(empty)\n");
+ }
+
+ for (uint32_t i = 0;
+ i < store->items.Length();
+ i++)
+ {
+ printf ("Run[% 2d]: '%s' ", i, store->items[i].platformFont.BeginReading());
+
+ for (int j = 0; j < store->items[i].num_glyphs; j++)
+ printf ("%d ", int(store->items[i].glyphs[j].index));
+
+ printf ("\n");
+ }
+}
+
+void
+DumpTestExpect (TestEntry *test) {
+ for (uint32_t i = 0; i < test->expectItems.Length(); i++) {
+ printf ("Run[% 2d]: '%s' ", i, test->expectItems[i].fontName.BeginReading());
+ for (uint32_t j = 0; j < test->expectItems[i].glyphs.data.Length(); j++)
+ printf ("%d ", int(test->expectItems[i].glyphs.data[j]));
+
+ printf ("\n");
+ }
+}
+
+void SetupTests(nsTArray<TestEntry>& testList);
+
+static bool
+RunTest (TestEntry *test, gfxContext *ctx) {
+ RefPtr<gfxFontGroup> fontGroup;
+
+ fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->utf8FamilyString), &test->fontStyle, nullptr, nullptr, 1.0);
+
+ RefPtr<gfxTextRun> textRun;
+ gfxTextRunFactory::Parameters params = {
+ ctx, nullptr, nullptr, nullptr, 0, 60
+ };
+ uint32_t flags = gfxTextRunFactory::TEXT_IS_PERSISTENT;
+ if (test->isRTL) {
+ flags |= gfxTextRunFactory::TEXT_IS_RTL;
+ }
+ uint32_t length;
+ if (test->stringType == S_ASCII) {
+ flags |= gfxTextRunFactory::TEXT_IS_ASCII | gfxTextRunFactory::TEXT_IS_8BIT;
+ length = strlen(test->string);
+ textRun = fontGroup->MakeTextRun(
+ reinterpret_cast<const uint8_t*>(test->string), length, &params, flags);
+ } else {
+ NS_ConvertUTF8toUTF16 str(nsDependentCString(test->string));
+ length = str.Length();
+ textRun = fontGroup->MakeTextRun(str.get(), length, &params, flags);
+ }
+
+ gfxFontTestStore::NewStore();
+ textRun->Draw(ctx, gfxPoint(0,0), DrawMode::GLYPH_FILL, 0, length, nullptr, nullptr, nullptr);
+ gfxFontTestStore *s = gfxFontTestStore::CurrentStore();
+
+ if (!test->Check(s)) {
+ DumpStore(s);
+ printf (" expected:\n");
+ DumpTestExpect(test);
+ gfxFontTestStore::DeleteStore();
+ return false;
+ }
+
+ gfxFontTestStore::DeleteStore();
+
+ return true;
+}
+
+TEST(Gfx, FontSelection) {
+ int passed = 0;
+ int failed = 0;
+
+ // set up the tests
+ nsTArray<TestEntry> testList;
+ SetupTests(testList);
+
+ RefPtr<gfxContext> context = MakeContext();
+
+ for (uint32_t test = 0;
+ test < testList.Length();
+ test++)
+ {
+ bool result = RunTest (&testList[test], context);
+ if (result) {
+ passed++;
+ } else {
+ printf ("Test %d failed\n", test);
+ failed++;
+ }
+ }
+}
+
+// The tests themselves
+
+#include "gfxFontSelectionTests.h"