Home | History | Annotate | Download | only in tests
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ppapi/tests/test_browser_font.h"
      6 
      7 #include <string.h>
      8 
      9 #include "ppapi/tests/test_utils.h"
     10 #include "ppapi/tests/testing_instance.h"
     11 #include "ppapi/cpp/image_data.h"
     12 #include "ppapi/cpp/trusted/browser_font_trusted.h"
     13 
     14 REGISTER_TEST_CASE(BrowserFont);
     15 
     16 bool TestBrowserFont::Init() {
     17   return true;
     18 }
     19 
     20 void TestBrowserFont::RunTests(const std::string& filter) {
     21   RUN_TEST(FontFamilies, filter);
     22   RUN_TEST(Measure, filter);
     23   RUN_TEST(MeasureRTL, filter);
     24   RUN_TEST(CharPos, filter);
     25   // This test is disabled. It doesn't currently pass. See the
     26   // CharacterOffsetForPixel API.
     27   //RUN_TEST(CharPosRTL, filter);
     28   RUN_TEST(Draw, filter);
     29 }
     30 
     31 // Just tests that GetFontFamilies is hooked up & returns something.
     32 std::string TestBrowserFont::TestFontFamilies() {
     33   // This function is only supported out-of-process.
     34   const PPB_Testing_Private* testing_interface = GetTestingInterface();
     35   if (testing_interface && !testing_interface->IsOutOfProcess())
     36     PASS();
     37 
     38   pp::Var families = pp::BrowserFont_Trusted::GetFontFamilies(instance_);
     39 
     40   ASSERT_TRUE(families.is_string());
     41   ASSERT_TRUE(!families.AsString().empty());
     42   PASS();
     43 }
     44 
     45 // Tests that measuring text behaves reasonably. We aren't sure if the browser
     46 // will be doing kerning or something for the particular default font, so we
     47 // just make a string that we're pretty sure should be more than twice as long
     48 // as another one, and verify that condition.
     49 std::string TestBrowserFont::TestMeasure() {
     50   pp::BrowserFontDescription desc;
     51   pp::BrowserFont_Trusted font(instance_, desc);
     52 
     53   int32_t length1 = font.MeasureText(pp::BrowserFontTextRun("WWW"));
     54   ASSERT_TRUE(length1 > 0);
     55   int32_t length2 = font.MeasureText(pp::BrowserFontTextRun("WWWWWWWW"));
     56 
     57   ASSERT_TRUE(length2 >= length1 * 2);
     58   PASS();
     59 }
     60 
     61 std::string TestBrowserFont::TestMeasureRTL() {
     62   pp::BrowserFontDescription desc;
     63   pp::BrowserFont_Trusted font(instance_, desc);
     64 
     65   // Mixed string, two chars of LTR, two of RTL, then two of LTR.
     66   // Note this is in UTF-8 so has more than 6 bytes.
     67   std::string mixed("AB\xd7\x94\xd7\x97ZZ");
     68   const int kNumChars = 6;
     69   pp::BrowserFontTextRun run(mixed);
     70 
     71   // Note that since this is UTF-8, the two RTL chars are two bytes each.
     72   int32_t len[kNumChars];
     73   len[0] = font.PixelOffsetForCharacter(run, 0);
     74   len[1] = font.PixelOffsetForCharacter(run, 1);
     75   len[2] = font.PixelOffsetForCharacter(run, 2);
     76   len[3] = font.PixelOffsetForCharacter(run, 3);
     77   len[4] = font.PixelOffsetForCharacter(run, 4);
     78   len[5] = font.PixelOffsetForCharacter(run, 5);
     79 
     80   // First three chars should be increasing.
     81   ASSERT_TRUE(len[0] >= 0);
     82   ASSERT_TRUE(len[1] > len[0]);
     83   ASSERT_TRUE(len[3] > len[1]);
     84   ASSERT_TRUE(len[2] > len[3]);
     85   ASSERT_TRUE(len[4] > len[2]);
     86   ASSERT_TRUE(len[5] > len[4]);
     87 
     88   // Test the same sequence with force LTR. The offsets should appear in
     89   // sequence.
     90   pp::BrowserFontTextRun forced_run(mixed, false, true);
     91   len[0] = font.PixelOffsetForCharacter(forced_run, 0);
     92   len[1] = font.PixelOffsetForCharacter(forced_run, 1);
     93   len[2] = font.PixelOffsetForCharacter(forced_run, 2);
     94   len[3] = font.PixelOffsetForCharacter(forced_run, 3);
     95   len[4] = font.PixelOffsetForCharacter(forced_run, 4);
     96   len[5] = font.PixelOffsetForCharacter(forced_run, 5);
     97   for (int i = 1; i < kNumChars; i++)
     98     ASSERT_TRUE(len[i] > len[i - 1]);
     99 
    100   PASS();
    101 }
    102 
    103 // Tests that the character/pixel offset functions correctly round-trip.
    104 std::string TestBrowserFont::TestCharPos() {
    105   pp::BrowserFontDescription desc;
    106   pp::BrowserFont_Trusted font(instance_, desc);
    107 
    108   pp::BrowserFontTextRun run("Hello, world");
    109   uint32_t original_char = 3;
    110   uint32_t pixel_offset = font.PixelOffsetForCharacter(run, original_char);
    111   ASSERT_TRUE(pixel_offset > 0);
    112 
    113   uint32_t computed_char = font.CharacterOffsetForPixel(
    114       run, static_cast<int32_t>(pixel_offset));
    115   ASSERT_TRUE(computed_char == original_char);
    116 
    117   PASS();
    118 }
    119 
    120 // Tests that we can get character positions in a mixed LTR/RTL run.
    121 std::string TestBrowserFont::TestCharPosRTL() {
    122   pp::BrowserFontDescription desc;
    123   pp::BrowserFont_Trusted font(instance_, desc);
    124 
    125   // Mixed string, two chars of LTR, two of RTL, than two of LTR.
    126   // Note this is in UTF-8 so has more than 6 bytes.
    127   std::string mixed("AB\xd7\x94\xd7\x97ZZ");
    128 
    129   pp::BrowserFontTextRun run(mixed);
    130   static const int kNumChars = 6;
    131   int expected_char_sequence[kNumChars] = { 0, 1, 3, 2, 4, 5 };
    132 
    133   // Check that the characters appear in the order we expect.
    134   int pixel_width = font.MeasureText(pp::BrowserFontTextRun(mixed));
    135   int last_sequence = 0;  // Index into expected_char_sequence.
    136   for (int x = 0; x < pixel_width; x++) {
    137     int cur_char = font.CharacterOffsetForPixel(run, x);
    138     if (cur_char != expected_char_sequence[last_sequence]) {
    139       // This pixel has a different character. It should be the next one in
    140       // the sequence for it to be correct.
    141       last_sequence++;
    142       ASSERT_TRUE(last_sequence < kNumChars);
    143       ASSERT_TRUE(cur_char == expected_char_sequence[last_sequence]);
    144     }
    145   }
    146 
    147   // Try the same string with force LTR. The characters should all appear in
    148   // sequence.
    149   pp::BrowserFontTextRun forced_run(mixed, false, true);
    150   int last_forced_char = 0;  // Char index into the forced sequence.
    151   for (int x = 0; x < pixel_width; x++) {
    152     int cur_char = font.CharacterOffsetForPixel(forced_run, x);
    153     if (cur_char != last_forced_char) {
    154       last_forced_char++;
    155       ASSERT_TRUE(cur_char == last_forced_char);
    156     }
    157   }
    158 
    159   PASS();
    160 }
    161 
    162 // Tests that drawing some text produces "some" output.
    163 std::string TestBrowserFont::TestDraw() {
    164   pp::BrowserFontDescription desc;
    165   desc.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE);
    166   desc.set_size(10);
    167   pp::BrowserFont_Trusted font(instance_, desc);
    168 
    169   const pp::Size kSize(30, 10);
    170   pp::ImageData image(instance_,
    171                       PP_IMAGEDATAFORMAT_BGRA_PREMUL,  // 0xAARRGGBB
    172                       kSize,
    173                       false);  // init_to_zero
    174   ASSERT_FALSE(image.is_null());
    175 
    176   // Draw black text on white canvas.
    177   memset(image.data(), 0xFF, 4 * kSize.GetArea());
    178   font.DrawSimpleText(&image,
    179                       "Hello",
    180                       pp::Point(0, 10),  // Baseline position.
    181                       0xFF000000,  // Black text.
    182                       true);  // image_data_is_opaque.
    183 
    184   // Expect that at least a few pixels are non-white (text).
    185   // Due to blending, there may be rounding errors and
    186   // checking for exact black may not be correct.
    187   // Also expect that all pixels are opaque.
    188   const uint32_t kRGBMask = 0x00FFFFFF;
    189   const uint32_t kAlphaMask = 0xFF000000;
    190   int text_pixels = 0, opaque_pixels = 0;
    191   const uint32_t* pixels = static_cast<const uint32_t*>(image.data());
    192   for (int i = 0; i < kSize.GetArea(); ++i) {
    193     if ((pixels[i] & kRGBMask) != kRGBMask)
    194       ++text_pixels;
    195     if ((pixels[i] & kAlphaMask) == kAlphaMask)
    196       ++opaque_pixels;
    197   }
    198   ASSERT_GT(text_pixels, 0);
    199   ASSERT_EQ(opaque_pixels, kSize.GetArea());
    200   PASS();
    201 }
    202