1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "renderer/unix/pango_wrapper_interface.h"
31 #include "renderer/unix/text_renderer.h"
32 #include "testing/base/public/gmock.h"
33 #include "testing/base/public/gunit.h"
34 
35 using ::testing::Expectation;
36 using ::testing::Return;
37 
38 namespace mozc {
39 namespace renderer {
40 namespace gtk {
41 
42 class FontSpecMock : public FontSpecInterface {
43  public:
44   MOCK_CONST_METHOD1(GetFontAlignment, PangoAlignment(FONT_TYPE font_type));
45   MOCK_CONST_METHOD1(GetFontAttributes, PangoAttrList *(FONT_TYPE font_type));
46   MOCK_CONST_METHOD1(GetFontDescription,
47                      const PangoFontDescription *(FONT_TYPE font_type));
48   MOCK_METHOD1(Reload, void(const string &font_description));
49 };
50 
51 class PangoWrapperMock : public PangoWrapperInterface {
52  public:
53   MOCK_METHOD3(RendererDrawLayout,
54                void(PangoLayoutWrapperInterface *layout, int x, int y));
55   MOCK_METHOD0(GetContext, PangoContext *());
56   MOCK_METHOD1(CopyAttributes, PangoAttrList *(PangoAttrList *attr));
57   MOCK_METHOD1(AttributesUnref, void(PangoAttrList *attr));
58 };
59 
60 class PangoLayoutWrapperMock : public PangoLayoutWrapperInterface {
61  public:
62   MOCK_METHOD1(SetText, void(const string &text));
63   MOCK_METHOD1(SetAlignment, void(PangoAlignment align));
64   MOCK_METHOD1(SetAttributes, void(PangoAttrList *attr));
65   MOCK_METHOD1(SetFontDescription, void(const PangoFontDescription *font_desc));
66   MOCK_METHOD1(SetWidth, void(int width));
67   MOCK_METHOD1(SetHeight, void(int height));
68   MOCK_CONST_METHOD0(GetPixelSize, Size());
69   MOCK_METHOD0(GetPangoLayout, PangoLayout *());
70 };
71 
72 class TextRendererTest : public testing::Test {
73  protected:
SetUpPangoMock(TextRenderer * text_renderer)74   PangoWrapperMock *SetUpPangoMock(TextRenderer *text_renderer) {
75     PangoWrapperMock *mock = new PangoWrapperMock();
76     text_renderer->pango_.reset(mock);
77     return mock;
78   }
SetUpFontSpecMock(TextRenderer * text_renderer)79   FontSpecMock *SetUpFontSpecMock(TextRenderer *text_renderer) {
80     FontSpecMock *mock = new FontSpecMock();
81     text_renderer->font_spec_.reset(mock);
82     return mock;
83   }
84 };
85 
TEST_F(TextRendererTest,GetPixelSizeTest)86 TEST_F(TextRendererTest, GetPixelSizeTest) {
87   FontSpecMock *font_spec_mock = new FontSpecMock();
88   TextRenderer text_renderer(font_spec_mock);
89   PangoWrapperMock *pango_mock = SetUpPangoMock(&text_renderer);
90 
91   const string text = "hogehoge";
92   PangoLayoutWrapperMock layout_mock;
93   PangoAlignment align = PANGO_ALIGN_CENTER;
94   PangoAttrList *attributes = reinterpret_cast<PangoAttrList*>(0xabcdef01);
95   PangoAttrList *copied_attributes
96       = reinterpret_cast<PangoAttrList*>(0x237492);
97   PangoFontDescription *font_desc
98       = reinterpret_cast<PangoFontDescription*>(0x01abcdef);
99   FontSpecInterface::FONT_TYPE font_type
100       = FontSpecInterface::FONTSET_FOOTER_LABEL;
101   Size size(12, 34);
102 
103   Expectation set_text_expectation
104       = EXPECT_CALL(layout_mock, SetText(text));
105   Expectation set_alignment_expectation
106       = EXPECT_CALL(layout_mock, SetAlignment(align));
107   Expectation set_attributes
108       = EXPECT_CALL(layout_mock, SetAttributes(copied_attributes));
109   Expectation set_font_description_expectation
110       = EXPECT_CALL(layout_mock, SetFontDescription(font_desc));
111   EXPECT_CALL(*font_spec_mock, GetFontAlignment(font_type))
112       .WillOnce(Return(align));
113   EXPECT_CALL(*font_spec_mock, GetFontAttributes(font_type))
114       .WillOnce(Return(attributes));
115   EXPECT_CALL(*pango_mock, CopyAttributes(attributes))
116       .WillOnce(Return(copied_attributes));
117   EXPECT_CALL(*font_spec_mock, GetFontDescription(font_type))
118       .WillOnce(Return(font_desc));
119   Expectation get_pixel_expectation
120       = EXPECT_CALL(layout_mock, GetPixelSize())
121           .After(set_text_expectation)
122           .After(set_alignment_expectation)
123           .After(set_attributes)
124           .After(set_font_description_expectation)
125           .WillOnce(Return(size));
126   EXPECT_CALL(*pango_mock, AttributesUnref(copied_attributes))
127       .After(set_attributes);
128 
129   Size actual_size
130       = text_renderer.TextRenderer::GetPixelSizeInternal(font_type,
131                                                          text,
132                                                          &layout_mock);
133   EXPECT_EQ(actual_size.width, size.width);
134   EXPECT_EQ(actual_size.height, size.height);
135 }
136 
TEST_F(TextRendererTest,GetMultilinePixelSizeTest)137 TEST_F(TextRendererTest, GetMultilinePixelSizeTest) {
138   FontSpecMock *font_spec_mock = new FontSpecMock();
139   TextRenderer text_renderer(font_spec_mock);
140   PangoWrapperMock *pango_mock = SetUpPangoMock(&text_renderer);
141 
142   const string text = "hogehoge";
143   PangoLayoutWrapperMock layout_mock;
144   PangoAlignment align = PANGO_ALIGN_CENTER;
145   PangoAttrList *attributes = reinterpret_cast<PangoAttrList*>(0xabcdef01);
146   PangoAttrList *copied_attributes
147       = reinterpret_cast<PangoAttrList*>(0x237492);
148   PangoFontDescription *font_desc
149       = reinterpret_cast<PangoFontDescription*>(0x01abcdef);
150   FontSpecInterface::FONT_TYPE font_type
151       = FontSpecInterface::FONTSET_FOOTER_LABEL;
152   int width = 12345;
153   Size size(12, 34);
154 
155   Expectation set_text_expectation
156       = EXPECT_CALL(layout_mock, SetText(text));
157   Expectation set_alignment_expectation
158       = EXPECT_CALL(layout_mock, SetAlignment(align));
159   Expectation set_attributes
160       = EXPECT_CALL(layout_mock, SetAttributes(copied_attributes));
161   EXPECT_CALL(*pango_mock, CopyAttributes(attributes))
162       .WillOnce(Return(copied_attributes));
163   Expectation set_font_description_expectation
164       = EXPECT_CALL(layout_mock, SetFontDescription(font_desc));
165   Expectation set_width_expectation
166       = EXPECT_CALL(layout_mock, SetWidth(width * PANGO_SCALE));
167   EXPECT_CALL(*font_spec_mock, GetFontAlignment(font_type))
168       .WillOnce(Return(align));
169   EXPECT_CALL(*font_spec_mock, GetFontAttributes(font_type))
170       .WillOnce(Return(attributes));
171   EXPECT_CALL(*font_spec_mock, GetFontDescription(font_type))
172       .WillOnce(Return(font_desc));
173   Expectation get_pixel_expectation
174       = EXPECT_CALL(layout_mock, GetPixelSize())
175           .After(set_text_expectation)
176           .After(set_alignment_expectation)
177           .After(set_attributes)
178           .After(set_font_description_expectation)
179           .WillOnce(Return(size));
180   EXPECT_CALL(*pango_mock, AttributesUnref(copied_attributes))
181       .After(set_attributes);
182 
183   Size actual_size
184       = text_renderer.TextRenderer::GetMultiLinePixelSizeInternal(font_type,
185                                                                   text,
186                                                                   width,
187                                                                   &layout_mock);
188   EXPECT_EQ(actual_size.width, size.width);
189   EXPECT_EQ(actual_size.height, size.height);
190 }
191 
TEST_F(TextRendererTest,RenderTextTest)192 TEST_F(TextRendererTest, RenderTextTest) {
193   FontSpecMock *font_spec_mock = new FontSpecMock();
194   TextRenderer text_renderer(font_spec_mock);
195   PangoWrapperMock *pango_mock = SetUpPangoMock(&text_renderer);
196   PangoLayoutWrapperMock layout_mock;
197 
198   const string text = "hogehoge";
199   Rect rect(10, 20, 30, 40);
200   Size size(12, 34);
201   PangoAlignment align = PANGO_ALIGN_CENTER;
202   PangoAttrList *attributes = reinterpret_cast<PangoAttrList*>(0xabcdef01);
203   PangoAttrList *copied_attributes
204       = reinterpret_cast<PangoAttrList*>(0x237492);
205   PangoFontDescription *font_desc
206       = reinterpret_cast<PangoFontDescription*>(0x01abcdef);
207   FontSpecInterface::FONT_TYPE font_type
208       = FontSpecInterface::FONTSET_FOOTER_LABEL;
209 
210   EXPECT_CALL(*font_spec_mock, GetFontAlignment(font_type))
211       .WillRepeatedly(Return(align));
212   EXPECT_CALL(*font_spec_mock, GetFontAttributes(font_type))
213       .WillRepeatedly(Return(attributes));
214   EXPECT_CALL(*font_spec_mock, GetFontDescription(font_type))
215       .WillRepeatedly(Return(font_desc));
216 
217   Expectation set_alignment_expectation
218       = EXPECT_CALL(layout_mock, SetAlignment(align));
219   Expectation set_attributes
220       = EXPECT_CALL(layout_mock, SetAttributes(copied_attributes));
221   EXPECT_CALL(*pango_mock, CopyAttributes(attributes))
222       .WillOnce(Return(copied_attributes));
223   Expectation set_font_description_expectation
224       = EXPECT_CALL(layout_mock, SetFontDescription(font_desc));
225 
226   Expectation set_text_expectation
227       = EXPECT_CALL(layout_mock, SetText(text));
228   Expectation set_width_expectation
229       = EXPECT_CALL(layout_mock, SetWidth(rect.size.width * PANGO_SCALE));
230   Expectation set_height_expectation
231       = EXPECT_CALL(layout_mock, SetHeight(rect.size.height * PANGO_SCALE));
232   Expectation get_pixel_size_expectation
233       = EXPECT_CALL(layout_mock, GetPixelSize())
234           .WillOnce(Return(size));
235   EXPECT_CALL(*pango_mock, AttributesUnref(copied_attributes))
236       .After(set_attributes);
237 
238   // Vertical centering
239   const int expected_x = rect.origin.x * PANGO_SCALE;
240   const int expected_y
241       = (rect.origin.y + (rect.size.height - size.height)/2) * PANGO_SCALE;
242 
243   Expectation rendering_expectation =
244       EXPECT_CALL(*pango_mock,
245                   RendererDrawLayout(&layout_mock, expected_x, expected_y))
246           .After(set_alignment_expectation)
247           .After(set_attributes)
248           .After(set_font_description_expectation)
249           .After(set_text_expectation)
250           .After(set_width_expectation)
251           .After(set_height_expectation)
252           .After(get_pixel_size_expectation);
253 
254   text_renderer.RenderTextInternal(text, rect, font_type, &layout_mock);
255 }
256 
TEST_F(TextRendererTest,ReloadFontConfigTest)257 TEST_F(TextRendererTest, ReloadFontConfigTest) {
258   FontSpecMock *font_spec_mock = new FontSpecMock();
259   TextRenderer text_renderer(font_spec_mock);
260   const char kDummyFontDescription[] = "Foo,Bar,Baz";
261 
262   EXPECT_CALL(*font_spec_mock, Reload(kDummyFontDescription));
263   text_renderer.ReloadFontConfig(kDummyFontDescription);
264 }
265 
266 }  // namespace gtk
267 }  // namespace renderer
268 }  // namespace mozc
269