Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / gfx / tests / gfxFontSelectionTest.cpp
blob62ae320d675184ca787ea4afd7b1bfd3d12c1cc6
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is Mozilla Corporation code.
17 * The Initial Developer of the Original Code is Mozilla Foundation.
18 * Portions created by the Initial Developer are Copyright (C) 2007
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Vladimir Vukicevic <vladimir@pobox.com>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsCOMPtr.h"
39 #include "nsTArray.h"
40 #include "nsString.h"
41 #include "nsDependentString.h"
43 #include "nsServiceManagerUtils.h"
44 #include "nsIPrefService.h"
45 #include "nsIPrefBranch.h"
47 #include "gfxContext.h"
48 #include "gfxFont.h"
49 #include "gfxPlatform.h"
50 #include "gfxTextRunWordCache.h"
52 #include "gfxFontTest.h"
54 #if defined(XP_MACOSX)
55 #include "gfxTestCocoaHelper.h"
56 #endif
58 #ifdef MOZ_WIDGET_GTK2
59 #include "gtk/gtk.h"
60 #endif
62 enum {
63 S_UTF8 = 0,
64 S_ASCII = 1
67 class FrameTextRunCache;
69 static gfxTextRunWordCache *gTextRunCache;
71 struct LiteralArray {
72 LiteralArray (unsigned long l1) {
73 data.AppendElement(l1);
75 LiteralArray (unsigned long l1, unsigned long l2) {
76 data.AppendElement(l1);
77 data.AppendElement(l2);
79 LiteralArray (unsigned long l1, unsigned long l2, unsigned long l3) {
80 data.AppendElement(l1);
81 data.AppendElement(l2);
82 data.AppendElement(l3);
84 LiteralArray (unsigned long l1, unsigned long l2, unsigned long l3, unsigned long l4) {
85 data.AppendElement(l1);
86 data.AppendElement(l2);
87 data.AppendElement(l3);
88 data.AppendElement(l4);
90 LiteralArray (unsigned long l1, unsigned long l2, unsigned long l3, unsigned long l4, unsigned long l5) {
91 data.AppendElement(l1);
92 data.AppendElement(l2);
93 data.AppendElement(l3);
94 data.AppendElement(l4);
95 data.AppendElement(l5);
98 LiteralArray (const LiteralArray& other) {
99 data = other.data;
102 nsTArray<unsigned long> data;
105 #define GLYPHS LiteralArray
107 struct TestEntry {
108 TestEntry (const char *aUTF8FamilyString,
109 const gfxFontStyle& aFontStyle,
110 const char *aString)
111 : utf8FamilyString(aUTF8FamilyString),
112 fontStyle(aFontStyle),
113 stringType(S_ASCII),
114 string(aString),
115 isRTL(PR_FALSE)
119 TestEntry (const char *aUTF8FamilyString,
120 const gfxFontStyle& aFontStyle,
121 int stringType,
122 const char *aString)
123 : utf8FamilyString(aUTF8FamilyString),
124 fontStyle(aFontStyle),
125 stringType(stringType),
126 string(aString),
127 isRTL(PR_FALSE)
131 struct ExpectItem {
132 ExpectItem(const nsCString& aFontName,
133 const LiteralArray& aGlyphs)
134 : fontName(aFontName), glyphs(aGlyphs)
137 PRBool Compare(const nsCString& aFontName,
138 cairo_glyph_t *aGlyphs,
139 int num_glyphs)
141 // bit that allowed for empty fontname to match all is commented
142 // out
143 if (/*!fontName.IsEmpty() &&*/ !fontName.Equals(aFontName))
144 return PR_FALSE;
146 if (num_glyphs != int(glyphs.data.Length()))
147 return PR_FALSE;
149 for (int j = 0; j < num_glyphs; j++) {
150 if (glyphs.data[j] != aGlyphs[j].index)
151 return PR_FALSE;
154 return PR_TRUE;
157 nsCString fontName;
158 LiteralArray glyphs;
161 void SetRTL()
163 isRTL = PR_TRUE;
166 // empty/NULL fontName means ignore font name
167 void Expect (const char *platform,
168 const char *fontName,
169 const LiteralArray& glyphs)
171 if (fontName)
172 Expect (platform, nsDependentCString(fontName), glyphs);
173 else
174 Expect (platform, nsCString(), glyphs);
177 void Expect (const char *platform,
178 const nsCString& fontName,
179 const LiteralArray& glyphs)
181 #if defined(XP_WIN)
182 if (strcmp(platform, "win32"))
183 return;
184 #elif defined(XP_MACOSX)
185 if (strcmp(platform, "macosx"))
186 return;
187 #elif defined(XP_UNIX)
188 if (strcmp(platform, "gtk2-pango"))
189 return;
190 #else
191 return;
192 #endif
194 expectItems.AppendElement(ExpectItem(fontName, glyphs));
197 PRBool Check (gfxFontTestStore *store) {
198 if (expectItems.Length() == 0 ||
199 store->items.Length() != expectItems.Length())
201 return PR_FALSE;
204 for (PRUint32 i = 0; i < expectItems.Length(); i++) {
205 if (!expectItems[i].Compare(store->items[i].platformFont,
206 store->items[i].glyphs,
207 store->items[i].num_glyphs))
208 return PR_FALSE;
211 return PR_TRUE;
214 const char *utf8FamilyString;
215 gfxFontStyle fontStyle;
217 int stringType;
218 const char *string;
219 PRPackedBool isRTL;
221 nsTArray<ExpectItem> expectItems;
224 nsTArray<TestEntry> testList;
226 already_AddRefed<gfxContext>
227 MakeContext ()
229 const int size = 200;
231 nsRefPtr<gfxASurface> surface;
233 surface = gfxPlatform::GetPlatform()->
234 CreateOffscreenSurface(gfxIntSize(size, size),
235 gfxASurface::ContentFromFormat(gfxASurface::ImageFormatRGB24));
236 gfxContext *ctx = new gfxContext(surface);
237 NS_IF_ADDREF(ctx);
238 return ctx;
241 TestEntry*
242 AddTest (const char *utf8FamilyString,
243 const gfxFontStyle& fontStyle,
244 int stringType,
245 const char *string)
247 TestEntry te (utf8FamilyString,
248 fontStyle,
249 stringType,
250 string);
252 testList.AppendElement(te);
254 return &(testList[testList.Length()-1]);
257 void SetupTests();
259 void
260 DumpStore (gfxFontTestStore *store) {
261 if (store->items.Length() == 0) {
262 printf ("(empty)\n");
265 for (PRUint32 i = 0;
266 i < store->items.Length();
267 i++)
269 printf ("Run[% 2d]: '%s' ", i, nsPromiseFlatCString(store->items[i].platformFont).get());
271 for (int j = 0; j < store->items[i].num_glyphs; j++)
272 printf ("%d ", int(store->items[i].glyphs[j].index));
274 printf ("\n");
278 void
279 DumpTestExpect (TestEntry *test) {
280 for (PRUint32 i = 0; i < test->expectItems.Length(); i++) {
281 printf ("Run[% 2d]: '%s' ", i, nsPromiseFlatCString(test->expectItems[i].fontName).get());
282 for (PRUint32 j = 0; j < test->expectItems[i].glyphs.data.Length(); j++)
283 printf ("%d ", int(test->expectItems[i].glyphs.data[j]));
285 printf ("\n");
289 PRBool
290 RunTest (TestEntry *test, gfxContext *ctx) {
291 nsRefPtr<gfxFontGroup> fontGroup;
293 fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->utf8FamilyString), &test->fontStyle, nsnull);
295 nsAutoPtr<gfxTextRun> textRun;
296 gfxTextRunFactory::Parameters params = {
297 ctx, nsnull, nsnull, nsnull, 0, 60
299 PRUint32 flags = gfxTextRunFactory::TEXT_IS_PERSISTENT;
300 if (test->isRTL) {
301 flags |= gfxTextRunFactory::TEXT_IS_RTL;
303 PRUint32 length;
304 if (test->stringType == S_ASCII) {
305 flags |= gfxTextRunFactory::TEXT_IS_ASCII | gfxTextRunFactory::TEXT_IS_8BIT;
306 length = strlen(test->string);
307 textRun = gfxTextRunWordCache::MakeTextRun(reinterpret_cast<const PRUint8*>(test->string), length, fontGroup, &params, flags);
308 } else {
309 NS_ConvertUTF8toUTF16 str(nsDependentCString(test->string));
310 length = str.Length();
311 textRun = gfxTextRunWordCache::MakeTextRun(str.get(), length, fontGroup, &params, flags);
314 gfxFontTestStore::NewStore();
315 textRun->Draw(ctx, gfxPoint(0,0), 0, length, nsnull, nsnull);
316 gfxFontTestStore *s = gfxFontTestStore::CurrentStore();
318 gTextRunCache->RemoveTextRun(textRun);
320 if (!test->Check(s)) {
321 DumpStore(s);
322 printf (" expected:\n");
323 DumpTestExpect(test);
324 return PR_FALSE;
327 return PR_TRUE;
331 main (int argc, char **argv) {
332 int passed = 0;
333 int failed = 0;
335 #ifdef MOZ_WIDGET_GTK2
336 gtk_init(&argc, &argv);
337 #endif
338 #ifdef XP_MACOSX
339 CocoaPoolInit();
340 #endif
342 // Initialize XPCOM
343 nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
344 if (NS_FAILED(rv))
345 return -1;
347 rv = gfxPlatform::Init();
348 if (NS_FAILED(rv))
349 return -1;
351 gTextRunCache = new gfxTextRunWordCache();
353 // let's get all the xpcom goop out of the system
354 fflush (stderr);
355 fflush (stdout);
357 // don't need to query, we might need to set up some prefs later
358 if (0) {
359 nsresult rv;
361 nsCOMPtr<nsIPrefService> prefsvc = do_GetService(NS_PREFSERVICE_CONTRACTID);
362 if (!prefsvc) {
363 printf ("Pref svc get failed!\n");
366 nsCOMPtr<nsIPrefBranch> branch;
367 rv = prefsvc->GetBranch(nsnull, getter_AddRefs(branch));
368 if (NS_FAILED(rv))
369 printf ("Failed 0x%08x\n", rv);
371 nsXPIDLCString str;
372 rv = branch->GetCharPref("font.name.sans-serif.x-western", getter_Copies(str));
373 if (NS_FAILED(rv))
374 printf ("Failed[2] 0x%08x\n", rv);
376 printf ("sans-serif.x-western: %s\n", nsPromiseFlatCString(str).get());
379 // set up the tests
380 SetupTests();
382 nsRefPtr<gfxContext> context = MakeContext();
384 for (uint test = 0;
385 test < testList.Length();
386 test++)
388 printf ("==== Test %d\n", test);
389 PRBool result = RunTest (&testList[test], context);
390 if (result) {
391 printf ("Test %d succeeded\n", test);
392 passed++;
393 } else {
394 printf ("Test %d failed\n", test);
395 failed++;
399 printf ("PASSED: %d FAILED: %d\n", passed, failed);
400 fflush (stderr);
401 fflush (stdout);
404 // The tests themselves
406 #include "gfxFontSelectionTests.h"