Home | History | Annotate | Download | only in unittest
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "minikin/MeasuredText.h"
     18 
     19 #include <gtest/gtest.h>
     20 
     21 #include "minikin/LineBreaker.h"
     22 
     23 #include "FontTestUtils.h"
     24 #include "UnicodeUtils.h"
     25 
     26 namespace minikin {
     27 
     28 constexpr float CHAR_WIDTH = 10.0;  // Mock implementation always returns 10.0 for advance.
     29 
     30 TEST(MeasuredTextTest, RunTests) {
     31     constexpr uint32_t CHAR_COUNT = 6;
     32     constexpr float REPLACEMENT_WIDTH = 20.0f;
     33     auto font = buildFontCollection("Ascii.ttf");
     34 
     35     MeasuredTextBuilder builder;
     36 
     37     MinikinPaint paint1(font);
     38     paint1.size = 10.0f;  // make 1em = 10px
     39     builder.addStyleRun(0, 2, std::move(paint1), false /* is RTL */);
     40     builder.addReplacementRun(2, 4, REPLACEMENT_WIDTH, 0 /* locale list id */);
     41     MinikinPaint paint2(font);
     42     paint2.size = 10.0f;  // make 1em = 10px
     43     builder.addStyleRun(4, 6, std::move(paint2), false /* is RTL */);
     44 
     45     std::vector<uint16_t> text(CHAR_COUNT, 'a');
     46 
     47     std::unique_ptr<MeasuredText> measuredText =
     48             builder.build(text, true /* compute hyphenation */, false /* compute full layout */,
     49                           nullptr /* no hint */);
     50 
     51     ASSERT_TRUE(measuredText);
     52 
     53     // ReplacementRun assigns all width to the first character and leave zeros others.
     54     std::vector<float> expectedWidths = {CHAR_WIDTH, CHAR_WIDTH, REPLACEMENT_WIDTH,
     55                                          0,          CHAR_WIDTH, CHAR_WIDTH};
     56 
     57     EXPECT_EQ(expectedWidths, measuredText->widths);
     58 }
     59 
     60 TEST(MeasuredTextTest, getBoundsTest) {
     61     auto text = utf8ToUtf16("Hello, World!");
     62     auto font = buildFontCollection("Ascii.ttf");
     63 
     64     MeasuredTextBuilder builder;
     65     MinikinPaint paint(font);
     66     paint.size = 10.0f;
     67     builder.addStyleRun(0, text.size(), std::move(paint), false /* is RTL */);
     68     auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
     69                             nullptr /* no hint */);
     70 
     71     EXPECT_EQ(MinikinRect(0.0f, 0.0f, 0.0f, 0.0f), mt->getBounds(text, Range(0, 0)));
     72     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), mt->getBounds(text, Range(0, 1)));
     73     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), mt->getBounds(text, Range(0, 2)));
     74     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), mt->getBounds(text, Range(1, 2)));
     75     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 130.0f, 0.0f), mt->getBounds(text, Range(0, text.size())));
     76 }
     77 
     78 TEST(MeasuredTextTest, getBoundsTest_multiStyle) {
     79     auto text = utf8ToUtf16("Hello, World!");
     80     auto font = buildFontCollection("Ascii.ttf");
     81     uint32_t helloLength = 7;  // length of "Hello, "
     82 
     83     MeasuredTextBuilder builder;
     84     MinikinPaint paint(font);
     85     paint.size = 10.0f;
     86     builder.addStyleRun(0, helloLength, std::move(paint), false /* is RTL */);
     87     MinikinPaint paint2(font);
     88     paint2.size = 20.0f;
     89     builder.addStyleRun(helloLength, text.size(), std::move(paint2), false /* is RTL */);
     90     auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
     91                             nullptr /* no hint */);
     92 
     93     EXPECT_EQ(MinikinRect(0.0f, 0.0f, 0.0f, 0.0f), mt->getBounds(text, Range(0, 0)));
     94     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), mt->getBounds(text, Range(0, 1)));
     95     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), mt->getBounds(text, Range(0, 2)));
     96     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), mt->getBounds(text, Range(1, 2)));
     97     EXPECT_EQ(MinikinRect(0.0f, 0.0f, 0.0f, 0.0f), mt->getBounds(text, Range(7, 7)));
     98     EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), mt->getBounds(text, Range(7, 8)));
     99     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 30.0f, 0.0f), mt->getBounds(text, Range(6, 8)));
    100     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 190.0f, 0.0f), mt->getBounds(text, Range(0, text.size())));
    101 }
    102 
    103 TEST(MeasuredTextTest, getExtentTest) {
    104     auto text = utf8ToUtf16("Hello, World!");
    105     auto font = buildFontCollection("Ascii.ttf");
    106 
    107     MeasuredTextBuilder builder;
    108     MinikinPaint paint(font);
    109     paint.size = 10.0f;
    110     builder.addStyleRun(0, text.size(), std::move(paint), false /* is RTL */);
    111     auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
    112                             nullptr /* no hint */);
    113 
    114     EXPECT_EQ(MinikinExtent(0.0f, 0.0f), mt->getExtent(text, Range(0, 0)));
    115     EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), mt->getExtent(text, Range(0, 1)));
    116     EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), mt->getExtent(text, Range(0, 2)));
    117     EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), mt->getExtent(text, Range(1, 2)));
    118     EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), mt->getExtent(text, Range(0, text.size())));
    119 }
    120 
    121 TEST(MeasuredTextTest, getExtentTest_multiStyle) {
    122     auto text = utf8ToUtf16("Hello, World!");
    123     auto font = buildFontCollection("Ascii.ttf");
    124     uint32_t helloLength = 7;  // length of "Hello, "
    125 
    126     MeasuredTextBuilder builder;
    127     MinikinPaint paint(font);
    128     paint.size = 10.0f;
    129     builder.addStyleRun(0, helloLength, std::move(paint), false /* is RTL */);
    130     MinikinPaint paint2(font);
    131     paint2.size = 20.0f;
    132     builder.addStyleRun(helloLength, text.size(), std::move(paint2), false /* is RTL */);
    133     auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
    134                             nullptr /* no hint */);
    135 
    136     EXPECT_EQ(MinikinExtent(0.0f, 0.0f), mt->getExtent(text, Range(0, 0)));
    137     EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), mt->getExtent(text, Range(0, 1)));
    138     EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), mt->getExtent(text, Range(0, 2)));
    139     EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), mt->getExtent(text, Range(1, 2)));
    140     EXPECT_EQ(MinikinExtent(0.0f, 0.0f), mt->getExtent(text, Range(7, 7)));
    141     EXPECT_EQ(MinikinExtent(-160.0f, 40.0f), mt->getExtent(text, Range(7, 8)));
    142     EXPECT_EQ(MinikinExtent(-160.0f, 40.0f), mt->getExtent(text, Range(6, 8)));
    143     EXPECT_EQ(MinikinExtent(-160.0f, 40.0f), mt->getExtent(text, Range(0, text.size())));
    144 }
    145 
    146 TEST(MeasuredTextTest, buildLayoutTest) {
    147     auto text = utf8ToUtf16("Hello, World!");
    148     auto font = buildFontCollection("Ascii.ttf");
    149     Range fullContext(0, text.size());
    150 
    151     MeasuredTextBuilder builder;
    152     MinikinPaint paint(font);
    153     paint.size = 10.0f;
    154     builder.addStyleRun(0, text.size(), std::move(paint), false /* is RTL */);
    155     auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
    156                             nullptr /* no hint */);
    157 
    158     MinikinPaint samePaint(font);
    159     samePaint.size = 10.0f;
    160 
    161     Layout layout = mt->buildLayout(text, Range(0, 0), fullContext, samePaint,
    162                                     StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    163     EXPECT_EQ(0u, layout.nGlyphs());
    164 
    165     layout = mt->buildLayout(text, Range(0, 1), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
    166                              EndHyphenEdit::NO_EDIT);
    167     ASSERT_EQ(1u, layout.nGlyphs());
    168     EXPECT_TRUE(layout.getFont(0));
    169     EXPECT_EQ(0.0f, layout.getX(0));
    170     EXPECT_EQ(0.0f, layout.getY(0));
    171     EXPECT_EQ(10.0f, layout.getAdvance());
    172     EXPECT_EQ(10.0f, layout.getCharAdvance(0));
    173     EXPECT_EQ(1u, layout.getAdvances().size());
    174     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.getBounds());
    175 
    176     layout = mt->buildLayout(text, Range(0, 2), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
    177                              EndHyphenEdit::NO_EDIT);
    178     ASSERT_EQ(2u, layout.nGlyphs());
    179     EXPECT_TRUE(layout.getFont(0) && layout.getFont(0) == layout.getFont(1));
    180     EXPECT_EQ(0.0f, layout.getX(0));
    181     EXPECT_EQ(0.0f, layout.getY(0));
    182     EXPECT_EQ(10.0f, layout.getX(1));
    183     EXPECT_EQ(0.0f, layout.getY(1));
    184     EXPECT_EQ(20.0f, layout.getAdvance());
    185     EXPECT_EQ(10.0f, layout.getCharAdvance(0));
    186     EXPECT_EQ(10.0f, layout.getCharAdvance(1));
    187     EXPECT_EQ(2u, layout.getAdvances().size());
    188     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), layout.getBounds());
    189 
    190     layout = mt->buildLayout(text, Range(1, 2), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
    191                              EndHyphenEdit::NO_EDIT);
    192     ASSERT_EQ(1u, layout.nGlyphs());
    193     EXPECT_TRUE(layout.getFont(0));
    194     EXPECT_EQ(0.0f, layout.getX(0));
    195     EXPECT_EQ(0.0f, layout.getY(0));
    196     EXPECT_EQ(10.0f, layout.getAdvance());
    197     EXPECT_EQ(10.0f, layout.getCharAdvance(0));
    198     EXPECT_EQ(1u, layout.getAdvances().size());
    199     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.getBounds());
    200 
    201     layout = mt->buildLayout(text, Range(0, text.size()), fullContext, samePaint,
    202                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    203     ASSERT_EQ(text.size(), layout.nGlyphs());
    204     EXPECT_TRUE(layout.getFont(0));
    205     for (uint32_t i = 0; i < text.size(); ++i) {
    206         EXPECT_EQ(layout.getFont(0), layout.getFont(i)) << i;
    207         EXPECT_EQ(10.0f * i, layout.getX(i)) << i;
    208         EXPECT_EQ(0.0f, layout.getY(i)) << i;
    209         EXPECT_EQ(10.0f, layout.getCharAdvance(i)) << i;
    210     }
    211     EXPECT_EQ(130.0f, layout.getAdvance());
    212     EXPECT_EQ(text.size(), layout.getAdvances().size());
    213     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 130.0f, 0.0f), layout.getBounds());
    214 }
    215 
    216 TEST(MeasuredTextTest, buildLayoutTest_multiStyle) {
    217     auto text = utf8ToUtf16("Hello, World!");
    218     auto font = buildFontCollection("Ascii.ttf");
    219     uint32_t helloLength = 7;  // length of "Hello, "
    220     Range fullContext(0, text.size());
    221 
    222     MeasuredTextBuilder builder;
    223     MinikinPaint paint(font);
    224     paint.size = 10.0f;
    225     builder.addStyleRun(0, helloLength, std::move(paint), false /* is RTL */);
    226     MinikinPaint paint2(font);
    227     paint2.size = 20.0f;
    228     builder.addStyleRun(helloLength, text.size(), std::move(paint2), false /* is RTL */);
    229     auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
    230                             nullptr /* no hint */);
    231 
    232     MinikinPaint samePaint(font);
    233     samePaint.size = 10.0f;
    234 
    235     Layout layout = mt->buildLayout(text, Range(0, 0), fullContext, samePaint,
    236                                     StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    237     EXPECT_EQ(0u, layout.nGlyphs());
    238 
    239     layout = mt->buildLayout(text, Range(0, 1), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
    240                              EndHyphenEdit::NO_EDIT);
    241     ASSERT_EQ(1u, layout.nGlyphs());
    242     EXPECT_TRUE(layout.getFont(0));
    243     EXPECT_EQ(0.0f, layout.getX(0));
    244     EXPECT_EQ(0.0f, layout.getY(0));
    245     EXPECT_EQ(10.0f, layout.getAdvance());
    246     EXPECT_EQ(10.0f, layout.getCharAdvance(0));
    247     EXPECT_EQ(1u, layout.getAdvances().size());
    248     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.getBounds());
    249 
    250     layout = mt->buildLayout(text, Range(0, 2), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
    251                              EndHyphenEdit::NO_EDIT);
    252     ASSERT_EQ(2u, layout.nGlyphs());
    253     EXPECT_TRUE(layout.getFont(0) && layout.getFont(0) == layout.getFont(1));
    254     EXPECT_EQ(0.0f, layout.getX(0));
    255     EXPECT_EQ(0.0f, layout.getY(0));
    256     EXPECT_EQ(10.0f, layout.getX(1));
    257     EXPECT_EQ(0.0f, layout.getY(1));
    258     EXPECT_EQ(20.0f, layout.getAdvance());
    259     EXPECT_EQ(10.0f, layout.getCharAdvance(0));
    260     EXPECT_EQ(10.0f, layout.getCharAdvance(1));
    261     EXPECT_EQ(2u, layout.getAdvances().size());
    262     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), layout.getBounds());
    263 
    264     layout = mt->buildLayout(text, Range(1, 2), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
    265                              EndHyphenEdit::NO_EDIT);
    266     ASSERT_EQ(1u, layout.nGlyphs());
    267     EXPECT_TRUE(layout.getFont(0));
    268     EXPECT_EQ(0.0f, layout.getX(0));
    269     EXPECT_EQ(0.0f, layout.getY(0));
    270     EXPECT_EQ(10.0f, layout.getAdvance());
    271     EXPECT_EQ(10.0f, layout.getCharAdvance(0));
    272     EXPECT_EQ(1u, layout.getAdvances().size());
    273     EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.getBounds());
    274 
    275     layout = mt->buildLayout(text, Range(7, 7), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
    276                              EndHyphenEdit::NO_EDIT);
    277     EXPECT_EQ(0u, layout.nGlyphs());
    278 
    279     MinikinPaint samePaint2(font);
    280     samePaint2.size = 20.0f;
    281     layout = mt->buildLayout(text, Range(7, 8), fullContext, samePaint2, StartHyphenEdit::NO_EDIT,
    282                              EndHyphenEdit::NO_EDIT);
    283     ASSERT_EQ(1u, layout.nGlyphs());
    284     EXPECT_TRUE(layout.getFont(0));
    285     EXPECT_EQ(0.0f, layout.getX(0));
    286     EXPECT_EQ(0.0f, layout.getY(0));
    287     EXPECT_EQ(20.0f, layout.getAdvance());
    288     EXPECT_EQ(20.0f, layout.getCharAdvance(0));
    289     EXPECT_EQ(1u, layout.getAdvances().size());
    290     EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), layout.getBounds());
    291 }
    292 
    293 TEST(MeasuredTextTest, buildLayoutTest_differentPaint) {
    294     auto text = utf8ToUtf16("Hello, World!");
    295     auto font = buildFontCollection("Ascii.ttf");
    296     Range fullContext(0, text.size());
    297 
    298     MeasuredTextBuilder builder;
    299     MinikinPaint paint(font);
    300     paint.size = 10.0f;
    301     builder.addStyleRun(0, text.size(), std::move(paint), false /* is RTL */);
    302     auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
    303                             nullptr /* no hint */);
    304 
    305     MinikinPaint differentPaint(font);
    306     differentPaint.size = 20.0f;
    307 
    308     Layout layout = mt->buildLayout(text, Range(0, 0), fullContext, differentPaint,
    309                                     StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    310     EXPECT_EQ(0u, layout.nGlyphs());
    311 
    312     layout = mt->buildLayout(text, Range(0, 1), fullContext, differentPaint,
    313                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    314     ASSERT_EQ(1u, layout.nGlyphs());
    315     EXPECT_TRUE(layout.getFont(0));
    316     EXPECT_EQ(0.0f, layout.getX(0));
    317     EXPECT_EQ(0.0f, layout.getY(0));
    318     EXPECT_EQ(20.0f, layout.getAdvance());
    319     EXPECT_EQ(20.0f, layout.getCharAdvance(0));
    320     EXPECT_EQ(1u, layout.getAdvances().size());
    321     EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), layout.getBounds());
    322 
    323     layout = mt->buildLayout(text, Range(0, 2), fullContext, differentPaint,
    324                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    325     ASSERT_EQ(2u, layout.nGlyphs());
    326     EXPECT_TRUE(layout.getFont(0) && layout.getFont(0) == layout.getFont(1));
    327     EXPECT_EQ(0.0f, layout.getX(0));
    328     EXPECT_EQ(0.0f, layout.getY(0));
    329     EXPECT_EQ(20.0f, layout.getX(1));
    330     EXPECT_EQ(0.0f, layout.getY(1));
    331     EXPECT_EQ(40.0f, layout.getAdvance());
    332     EXPECT_EQ(20.0f, layout.getCharAdvance(0));
    333     EXPECT_EQ(20.0f, layout.getCharAdvance(1));
    334     EXPECT_EQ(2u, layout.getAdvances().size());
    335     EXPECT_EQ(MinikinRect(0.0f, 20.0f, 40.0f, 0.0f), layout.getBounds());
    336 
    337     layout = mt->buildLayout(text, Range(1, 2), fullContext, differentPaint,
    338                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    339     ASSERT_EQ(1u, layout.nGlyphs());
    340     EXPECT_TRUE(layout.getFont(0));
    341     EXPECT_EQ(0.0f, layout.getX(0));
    342     EXPECT_EQ(0.0f, layout.getY(0));
    343     EXPECT_EQ(20.0f, layout.getAdvance());
    344     EXPECT_EQ(20.0f, layout.getCharAdvance(0));
    345     EXPECT_EQ(1u, layout.getAdvances().size());
    346     EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), layout.getBounds());
    347 
    348     layout = mt->buildLayout(text, Range(0, text.size()), fullContext, differentPaint,
    349                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    350     ASSERT_EQ(text.size(), layout.nGlyphs());
    351     EXPECT_TRUE(layout.getFont(0));
    352     for (uint32_t i = 0; i < text.size(); ++i) {
    353         EXPECT_EQ(layout.getFont(0), layout.getFont(i)) << i;
    354         EXPECT_EQ(20.0f * i, layout.getX(i)) << i;
    355         EXPECT_EQ(0.0f, layout.getY(i)) << i;
    356         EXPECT_EQ(20.0f, layout.getCharAdvance(i)) << i;
    357     }
    358     EXPECT_EQ(260.0f, layout.getAdvance());
    359     EXPECT_EQ(text.size(), layout.getAdvances().size());
    360     EXPECT_EQ(MinikinRect(0.0f, 20.0f, 260.0f, 0.0f), layout.getBounds());
    361 }
    362 
    363 TEST(MeasuredTextTest, buildLayoutTest_multiStyle_differentPaint) {
    364     auto text = utf8ToUtf16("Hello, World!");
    365     auto font = buildFontCollection("Ascii.ttf");
    366     uint32_t helloLength = 7;  // length of "Hello, "
    367     Range fullContext(0, text.size());
    368 
    369     MeasuredTextBuilder builder;
    370     MinikinPaint paint(font);
    371     paint.size = 10.0f;
    372     builder.addStyleRun(0, helloLength, std::move(paint), false /* is RTL */);
    373     MinikinPaint paint2(font);
    374     paint2.size = 20.0f;
    375     builder.addStyleRun(helloLength, text.size(), std::move(paint2), false /* is RTL */);
    376     auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
    377                             nullptr /* no hint */);
    378 
    379     MinikinPaint differentPaint(font);
    380     differentPaint.size = 30.0f;
    381 
    382     Layout layout = mt->buildLayout(text, Range(0, 0), fullContext, differentPaint,
    383                                     StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    384     EXPECT_EQ(0u, layout.nGlyphs());
    385 
    386     layout = mt->buildLayout(text, Range(0, 1), fullContext, differentPaint,
    387                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    388     ASSERT_EQ(1u, layout.nGlyphs());
    389     EXPECT_TRUE(layout.getFont(0));
    390     EXPECT_EQ(0.0f, layout.getX(0));
    391     EXPECT_EQ(0.0f, layout.getY(0));
    392     EXPECT_EQ(30.0f, layout.getAdvance());
    393     EXPECT_EQ(30.0f, layout.getCharAdvance(0));
    394     EXPECT_EQ(1u, layout.getAdvances().size());
    395     EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), layout.getBounds());
    396 
    397     layout = mt->buildLayout(text, Range(0, 2), fullContext, differentPaint,
    398                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    399     ASSERT_EQ(2u, layout.nGlyphs());
    400     EXPECT_TRUE(layout.getFont(0) && layout.getFont(0) == layout.getFont(1));
    401     EXPECT_EQ(0.0f, layout.getX(0));
    402     EXPECT_EQ(0.0f, layout.getY(0));
    403     EXPECT_EQ(30.0f, layout.getX(1));
    404     EXPECT_EQ(0.0f, layout.getY(1));
    405     EXPECT_EQ(60.0f, layout.getAdvance());
    406     EXPECT_EQ(30.0f, layout.getCharAdvance(0));
    407     EXPECT_EQ(30.0f, layout.getCharAdvance(1));
    408     EXPECT_EQ(2u, layout.getAdvances().size());
    409     EXPECT_EQ(MinikinRect(0.0f, 30.0f, 60.0f, 0.0f), layout.getBounds());
    410 
    411     layout = mt->buildLayout(text, Range(1, 2), fullContext, differentPaint,
    412                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    413     ASSERT_EQ(1u, layout.nGlyphs());
    414     EXPECT_TRUE(layout.getFont(0));
    415     EXPECT_EQ(0.0f, layout.getX(0));
    416     EXPECT_EQ(0.0f, layout.getY(0));
    417     EXPECT_EQ(30.0f, layout.getAdvance());
    418     EXPECT_EQ(30.0f, layout.getCharAdvance(0));
    419     EXPECT_EQ(1u, layout.getAdvances().size());
    420     EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), layout.getBounds());
    421 
    422     layout = mt->buildLayout(text, Range(7, 7), fullContext, differentPaint,
    423                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    424     EXPECT_EQ(0u, layout.nGlyphs());
    425 
    426     layout = mt->buildLayout(text, Range(7, 8), fullContext, differentPaint,
    427                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    428     ASSERT_EQ(1u, layout.nGlyphs());
    429     EXPECT_TRUE(layout.getFont(0));
    430     EXPECT_EQ(0.0f, layout.getX(0));
    431     EXPECT_EQ(0.0f, layout.getY(0));
    432     EXPECT_EQ(30.0f, layout.getAdvance());
    433     EXPECT_EQ(30.0f, layout.getCharAdvance(0));
    434     EXPECT_EQ(1u, layout.getAdvances().size());
    435     EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), layout.getBounds());
    436 
    437     layout = mt->buildLayout(text, Range(6, 8), fullContext, differentPaint,
    438                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    439     ASSERT_EQ(2u, layout.nGlyphs());
    440     EXPECT_TRUE(layout.getFont(0) && layout.getFont(0) == layout.getFont(1));
    441     EXPECT_EQ(0.0f, layout.getX(0));
    442     EXPECT_EQ(0.0f, layout.getY(0));
    443     EXPECT_EQ(30.0f, layout.getX(1));
    444     EXPECT_EQ(0.0f, layout.getY(1));
    445     EXPECT_EQ(60.0f, layout.getAdvance());
    446     EXPECT_EQ(30.0f, layout.getCharAdvance(0));
    447     EXPECT_EQ(30.0f, layout.getCharAdvance(1));
    448     EXPECT_EQ(2u, layout.getAdvances().size());
    449     EXPECT_EQ(MinikinRect(0.0f, 30.0f, 60.0f, 0.0f), layout.getBounds());
    450 
    451     layout = mt->buildLayout(text, Range(0, text.size()), fullContext, differentPaint,
    452                              StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
    453     ASSERT_EQ(text.size(), layout.nGlyphs());
    454     EXPECT_TRUE(layout.getFont(0));
    455     for (uint32_t i = 0; i < text.size(); ++i) {
    456         EXPECT_EQ(layout.getFont(0), layout.getFont(i)) << i;
    457         EXPECT_EQ(30.0f * i, layout.getX(i)) << i;
    458         EXPECT_EQ(0.0f, layout.getY(i)) << i;
    459         EXPECT_EQ(30.0f, layout.getCharAdvance(i)) << i;
    460     }
    461     EXPECT_EQ(390.0f, layout.getAdvance());
    462     EXPECT_EQ(text.size(), layout.getAdvances().size());
    463     EXPECT_EQ(MinikinRect(0.0f, 30.0f, 390.0f, 0.0f), layout.getBounds());
    464 }
    465 
    466 }  // namespace minikin
    467