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/font_spec.h"
31 
32 #include "base/logging.h"
33 #include "protocol/renderer_style.pb.h"
34 #include "renderer/renderer_style_handler.h"
35 #include "renderer/unix/const.h"
36 
37 namespace mozc {
38 namespace renderer {
39 namespace gtk {
40 
41 namespace {
CreateAttrListByScaleColor(const RGBA & color,double scale)42 PangoAttrList *CreateAttrListByScaleColor(const RGBA &color, double scale) {
43   PangoAttrList *attributes = pango_attr_list_new();
44   pango_attr_list_insert(attributes, pango_attr_scale_new(scale));
45   pango_attr_list_insert(attributes, pango_attr_foreground_new(
46       color.red << 8, color.green << 8, color.blue << 8));
47   return attributes;
48 }
49 
RGBAColor2RGBA(const RendererStyle::RGBAColor & rgba)50 RGBA RGBAColor2RGBA(const RendererStyle::RGBAColor &rgba) {
51   RGBA result = {
52     static_cast<uint8>(rgba.r()),
53     static_cast<uint8>(rgba.g()),
54     static_cast<uint8>(rgba.b()),
55     static_cast<uint8>(rgba.a() * 255.0)
56   };
57   return result;
58 }
59 }  // namespace
60 
61 struct FontInfo {
62   PangoAlignment align;
63   PangoAttrList *attributes;
64   PangoFontDescription *font;
65 };
66 
FontSpec(GtkWrapperInterface * gtk)67 FontSpec::FontSpec(GtkWrapperInterface *gtk)
68   : fonts_(SIZE_OF_FONT_TYPE),
69     is_initialized_(false),
70     gtk_(gtk) {
71   LoadFontSpec(kDefaultFontDescription);
72 }
73 
~FontSpec()74 FontSpec::~FontSpec() {
75   if (is_initialized_) {
76     ReleaseFontSpec();
77   }
78 }
79 
Reload(const string & font_description)80 void FontSpec::Reload(const string &font_description) {
81   if (!is_initialized_) {
82     ReleaseFontSpec();
83   }
84   LoadFontSpec(font_description);
85 }
86 
ReleaseFontSpec()87 void FontSpec::ReleaseFontSpec() {
88   if (!is_initialized_) {
89     DLOG(ERROR) << "Font spec is not initilaized.";
90     return;
91   }
92   for (uint32 i = 0; i < fonts_.size(); ++i) {
93     pango_font_description_free(fonts_[i].font);
94     pango_attr_list_unref(fonts_[i].attributes);
95   }
96 }
97 
LoadFontSpec(const string & font_description)98 void FontSpec::LoadFontSpec(const string &font_description) {
99   if (is_initialized_) {
100     LOG(WARNING) << "Font spec is already loaded. reloading...";
101     ReleaseFontSpec();
102   }
103 
104   RendererStyle style;
105   RendererStyleHandler::GetRendererStyle(&style);
106   const RendererStyle::InfolistStyle infostyle = style.infolist_style();
107 
108   // Set alignments.
109   fonts_[FONTSET_CANDIDATE].align = PANGO_ALIGN_LEFT;
110   fonts_[FONTSET_DESCRIPTION].align = PANGO_ALIGN_LEFT;
111   fonts_[FONTSET_FOOTER_INDEX].align = PANGO_ALIGN_RIGHT;
112   fonts_[FONTSET_FOOTER_LABEL].align = PANGO_ALIGN_CENTER;
113   fonts_[FONTSET_FOOTER_SUBLABEL].align = PANGO_ALIGN_CENTER;
114   fonts_[FONTSET_SHORTCUT].align = PANGO_ALIGN_CENTER;
115   fonts_[FONTSET_INFOLIST_CAPTION].align = PANGO_ALIGN_LEFT;
116   fonts_[FONTSET_INFOLIST_TITLE].align = PANGO_ALIGN_LEFT;
117   fonts_[FONTSET_INFOLIST_DESCRIPTION].align = PANGO_ALIGN_LEFT;
118 
119   // Set font descriptions.
120   fonts_[FONTSET_CANDIDATE].font
121       = pango_font_description_from_string(font_description.c_str());
122   fonts_[FONTSET_DESCRIPTION].font
123       = pango_font_description_from_string(font_description.c_str());
124   fonts_[FONTSET_FOOTER_INDEX].font
125       = pango_font_description_from_string(font_description.c_str());
126   fonts_[FONTSET_FOOTER_LABEL].font
127       = pango_font_description_from_string(font_description.c_str());
128   fonts_[FONTSET_FOOTER_SUBLABEL].font
129       = pango_font_description_from_string(font_description.c_str());
130   fonts_[FONTSET_SHORTCUT].font
131       = pango_font_description_from_string(font_description.c_str());
132   fonts_[FONTSET_INFOLIST_CAPTION].font
133       = pango_font_description_from_string(font_description.c_str());
134   fonts_[FONTSET_INFOLIST_TITLE].font
135       = pango_font_description_from_string(font_description.c_str());
136   fonts_[FONTSET_INFOLIST_DESCRIPTION].font
137       = pango_font_description_from_string(font_description.c_str());
138 
139   // Set color and scales.
140   fonts_[FONTSET_CANDIDATE].attributes
141       = CreateAttrListByScaleColor(kDefaultColor, PANGO_SCALE_MEDIUM);
142   fonts_[FONTSET_DESCRIPTION].attributes
143       = CreateAttrListByScaleColor(kDescriptionColor, PANGO_SCALE_MEDIUM);
144   fonts_[FONTSET_FOOTER_INDEX].attributes
145       = CreateAttrListByScaleColor(kFooterIndexColor, PANGO_SCALE_SMALL);
146   fonts_[FONTSET_FOOTER_LABEL].attributes
147       = CreateAttrListByScaleColor(kFooterLabelColor, PANGO_SCALE_SMALL);
148   fonts_[FONTSET_FOOTER_SUBLABEL].attributes
149       = CreateAttrListByScaleColor(kFooterSubLabelColor, PANGO_SCALE_SMALL);
150   fonts_[FONTSET_SHORTCUT].attributes
151       = CreateAttrListByScaleColor(kShortcutColor, PANGO_SCALE_MEDIUM);
152   fonts_[FONTSET_INFOLIST_CAPTION].attributes
153       = CreateAttrListByScaleColor(
154           RGBAColor2RGBA(infostyle.caption_style().foreground_color()),
155           PANGO_SCALE_MEDIUM);
156   fonts_[FONTSET_INFOLIST_TITLE].attributes
157       =  CreateAttrListByScaleColor(
158           RGBAColor2RGBA(infostyle.title_style().foreground_color()),
159           PANGO_SCALE_MEDIUM);
160   fonts_[FONTSET_INFOLIST_DESCRIPTION].attributes
161       =  CreateAttrListByScaleColor(
162           RGBAColor2RGBA(infostyle.description_style().foreground_color()),
163           PANGO_SCALE_MEDIUM);
164   is_initialized_ = true;
165 }
166 
GetFontAlignment(FONT_TYPE font_type) const167 PangoAlignment FontSpec::GetFontAlignment(FONT_TYPE font_type) const {
168   DCHECK(0 <= font_type && font_type < SIZE_OF_FONT_TYPE);
169   return fonts_[font_type].align;
170 }
171 
GetFontAttributes(FONT_TYPE font_type) const172 PangoAttrList *FontSpec::GetFontAttributes(FONT_TYPE font_type) const {
173   DCHECK(0 <= font_type && font_type < SIZE_OF_FONT_TYPE);
174   return fonts_[font_type].attributes;
175 }
176 
GetFontDescription(FONT_TYPE font_type) const177 const PangoFontDescription *FontSpec::GetFontDescription(
178     FONT_TYPE font_type) const {
179   DCHECK(0 <= font_type && font_type < SIZE_OF_FONT_TYPE);
180   return fonts_[font_type].font;
181 }
182 
183 }  // namespace gtk
184 }  // namespace renderer
185 }  // namespace mozc
186