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