1 /* Fo
2  * fo-font-desc.c: Object type for a font description
3  *
4  * Copyright (C) 2003 Sun Microsystems
5  * Copyright (C) 2007 Menteith Consulting Ltd
6  *
7  * See COPYING for the status of this software.
8  */
9 
10 #include "fo-utils.h"
11 #include "fo-object.h"
12 #include "fo-font-desc-private.h"
13 #include "fo-libfo-context.h"
14 
15 const char *fo_font_desc_error_messages [] = {
16   N_("FoFontDesc error")
17 };
18 
19 struct _FoFontDesc
20 {
21   FoObject      parent_instance;
22 
23   PangoFontDescription *font_desc;
24 };
25 
26 struct _FoFontDescClass
27 {
28   FoObjectClass parent_class;
29 };
30 
31 static void fo_font_desc_class_init (FoFontDescClass *klass);
32 static void fo_font_desc_finalize   (GObject        *object);
33 
34 static gpointer parent_class;
35 
36 /**
37  * fo_font_desc_error_quark:
38  *
39  * Get the error quark for #FoFontDesc.
40  *
41  * If the quark does not yet exist, create it.
42  *
43  * Return value: #GQuark associated with #FoFontDesc errors.
44  **/
45 GQuark
fo_font_desc_error_quark(void)46 fo_font_desc_error_quark (void)
47 {
48   static GQuark quark = 0;
49   if (quark == 0)
50     quark = g_quark_from_static_string ("FoFontDesc error");
51   return quark;
52 }
53 
54 /**
55  * fo_font_desc_get_type:
56  *
57  * Register the #FoFontDesc type if not already registered and
58  * return its #GType value.
59  *
60  * Return value: #GType of #FoFontDesc.
61  **/
62 GType
fo_font_desc_get_type(void)63 fo_font_desc_get_type (void)
64 {
65   static GType object_type = 0;
66 
67   if (!object_type)
68     {
69       static const GTypeInfo object_info =
70       {
71         sizeof (FoFontDescClass),
72         NULL,           /* base_init */
73         NULL,           /* base_finalize */
74         (GClassInitFunc) fo_font_desc_class_init,
75         NULL,           /* class_finalize */
76         NULL,           /* class_data */
77         sizeof (FoFontDesc),
78         0,              /* n_preallocs */
79 	(GInstanceInitFunc) NULL,
80 	NULL		/* value_table */
81       };
82 
83       object_type = g_type_register_static (FO_TYPE_OBJECT,
84                                             "FoFontDesc",
85                                             &object_info, 0);
86     }
87 
88   return object_type;
89 }
90 
91 /**
92  * fo_font_desc_class_init:
93  * @klass: #FoFontDesc object to initialise.
94  *
95  * Implements #GClassInitFunc for #FoFontDescClass.
96  **/
97 void
fo_font_desc_class_init(FoFontDescClass * klass)98 fo_font_desc_class_init (FoFontDescClass *klass)
99 {
100   GObjectClass *object_class = G_OBJECT_CLASS (klass);
101 
102   parent_class = g_type_class_peek_parent (klass);
103 
104   object_class->finalize = fo_font_desc_finalize;
105 }
106 
107 /**
108  * fo_font_desc_finalize:
109  * @object: #FoFontDesc object to finalize.
110  *
111  * Implements #GObjectFinalizeFunc for #FoFontDesc.
112  **/
113 void
fo_font_desc_finalize(GObject * object)114 fo_font_desc_finalize (GObject *object)
115 {
116   FoFontDesc *fo_font_desc;
117 
118   fo_font_desc = FO_FONT_DESC (object);
119 
120   if (fo_font_desc->font_desc != NULL)
121     {
122       pango_font_description_free (fo_font_desc->font_desc);
123       fo_font_desc->font_desc = NULL;
124     }
125 
126   G_OBJECT_CLASS (parent_class)->finalize (object);
127 }
128 
129 /**
130  * fo_font_desc_new:
131  *
132  * Creates a new #FoFontDesc.
133  *
134  * Return value: the newly created #FoFontDesc.
135  **/
136 FoFontDesc *
fo_font_desc_new(void)137 fo_font_desc_new (void)
138 {
139   FoFontDesc* fo_font_desc;
140 
141   fo_font_desc =
142     g_object_new (fo_font_desc_get_type (),
143 		  NULL);
144 
145   return fo_font_desc;
146 }
147 
148 FoFontDesc *
fo_font_desc_copy(const FoFontDesc * font_desc)149 fo_font_desc_copy (const FoFontDesc *font_desc)
150 {
151   FoFontDesc *new_font_desc = NULL;
152 
153   g_return_val_if_fail (FO_IS_FONT_DESC (font_desc), NULL);
154 
155   new_font_desc = fo_font_desc_new ();
156 
157   new_font_desc->font_desc =
158     pango_font_description_copy (font_desc->font_desc);
159 
160   return new_font_desc;
161 }
162 
163 void
fo_font_desc_set_family(FoFontDesc * font_desc,const char * family)164 fo_font_desc_set_family (FoFontDesc *font_desc,
165 			 const char *family)
166 {
167   g_return_if_fail (FO_IS_FONT_DESC (font_desc));
168 
169   pango_font_description_set_family (font_desc->font_desc,
170 				     family);
171 }
172 
173 void
fo_font_desc_set_size(FoFontDesc * font_desc,gfloat size)174 fo_font_desc_set_size (FoFontDesc *font_desc,
175 		       gfloat      size)
176 {
177   g_return_if_fail (FO_IS_FONT_DESC (font_desc));
178 
179   pango_font_description_set_size (font_desc->font_desc,
180 				   size * PANGO_SCALE);
181 }
182 
183 static PangoStyle
fo_font_style_to_pango_style(FoEnumEnum font_style)184 fo_font_style_to_pango_style (FoEnumEnum font_style)
185 {
186   PangoStyle pango_font_style = PANGO_STYLE_NORMAL;
187 
188   /* Pango doesn't support 'backslant' styles so leave 'backslant'
189    * as 'normal'
190    */
191   if (font_style == FO_ENUM_ENUM_ITALIC)
192     {
193       pango_font_style = PANGO_STYLE_ITALIC;
194     }
195   else if (font_style == FO_ENUM_ENUM_OBLIQUE)
196     {
197       pango_font_style = PANGO_STYLE_OBLIQUE;
198     }
199 
200   return pango_font_style;
201 }
202 
203 /**
204  * fo_font_desc_set_style:
205  * @font_desc: #FoFontDesc to set
206  * @style:     New font style
207  *
208  * Sets the font style of @font_desc to @style.
209  **/
210 void
fo_font_desc_set_style(FoFontDesc * font_desc,FoEnumEnum style)211 fo_font_desc_set_style (FoFontDesc *font_desc,
212 			FoEnumEnum  style)
213 {
214   g_return_if_fail (FO_IS_FONT_DESC (font_desc));
215 
216   pango_font_description_set_style (font_desc->font_desc,
217 				    fo_font_style_to_pango_style (style));
218 }
219 
220 static PangoStretch
_font_stretch_to_pango_stretch(FoEnumEnum font_stretch)221 _font_stretch_to_pango_stretch (FoEnumEnum font_stretch)
222 {
223   PangoStretch pango_stretch = PANGO_STRETCH_NORMAL;
224 
225   switch (font_stretch)
226     {
227     case FO_ENUM_ENUM_ULTRA_CONDENSED:
228       pango_stretch = PANGO_STRETCH_ULTRA_CONDENSED;
229       break;
230 
231     case FO_ENUM_ENUM_EXTRA_CONDENSED:
232       pango_stretch = PANGO_STRETCH_EXTRA_CONDENSED;
233       break;
234 
235     case FO_ENUM_ENUM_CONDENSED:
236       pango_stretch = PANGO_STRETCH_CONDENSED;
237       break;
238 
239     case FO_ENUM_ENUM_SEMI_CONDENSED:
240       pango_stretch = PANGO_STRETCH_SEMI_CONDENSED;
241       break;
242 
243     case FO_ENUM_ENUM_SEMI_EXPANDED:
244       pango_stretch = PANGO_STRETCH_SEMI_EXPANDED;
245       break;
246 
247     case FO_ENUM_ENUM_EXPANDED:
248       pango_stretch = PANGO_STRETCH_EXPANDED;
249       break;
250 
251     case FO_ENUM_ENUM_EXTRA_EXPANDED:
252       pango_stretch = PANGO_STRETCH_EXTRA_EXPANDED;
253       break;
254 
255     case FO_ENUM_ENUM_ULTRA_EXPANDED:
256       pango_stretch = PANGO_STRETCH_ULTRA_EXPANDED;
257       break;
258 
259     default:
260       break;
261    }
262 
263   return pango_stretch;
264 }
265 
266 void
fo_font_desc_set_stretch(FoFontDesc * font_desc,FoEnumEnum stretch)267 fo_font_desc_set_stretch (FoFontDesc *font_desc,
268 			  FoEnumEnum  stretch)
269 {
270   g_return_if_fail (FO_IS_FONT_DESC (font_desc));
271 
272   pango_font_description_set_stretch (font_desc->font_desc,
273 				      _font_stretch_to_pango_stretch (stretch));
274 }
275 
276 static PangoVariant
fo_font_variant_to_pango_variant(FoEnumEnum font_variant)277 fo_font_variant_to_pango_variant (FoEnumEnum font_variant)
278 {
279   PangoVariant pango_font_variant = PANGO_VARIANT_NORMAL;
280 
281   if (font_variant == FO_ENUM_ENUM_SMALL_CAPS)
282     {
283       pango_font_variant = PANGO_VARIANT_SMALL_CAPS;
284     }
285 
286   return pango_font_variant;
287 }
288 
289 void
fo_font_desc_set_variant(FoFontDesc * font_desc,FoEnumEnum variant)290 fo_font_desc_set_variant (FoFontDesc *font_desc,
291 			  FoEnumEnum  variant)
292 {
293   g_return_if_fail (FO_IS_FONT_DESC (font_desc));
294 
295   pango_font_description_set_variant (font_desc->font_desc,
296 				      fo_font_variant_to_pango_variant (variant));
297 }
298 
299 void
fo_font_desc_set_weight(FoFontDesc * font_desc,gint weight)300 fo_font_desc_set_weight (FoFontDesc *font_desc,
301 			 gint      weight)
302 {
303   g_return_if_fail (FO_IS_FONT_DESC (font_desc));
304 
305   pango_font_description_set_weight (font_desc->font_desc,
306 				     weight);
307 }
308 
309 /**
310  * fo_font_desc_get_font_description:
311  * @fo_font_desc: #FoFontDesc.
312  *
313  * Get the #PangoFontDescription in @fo_font_desc.
314  *
315  * Return value: #PangoFontDescription in @fo_font_desc.
316  **/
317 PangoFontDescription *
fo_font_desc_get_font_description(const FoFontDesc * fo_font_desc)318 fo_font_desc_get_font_description (const FoFontDesc *fo_font_desc)
319 {
320   g_return_val_if_fail (fo_font_desc != NULL, NULL);
321 
322   return fo_font_desc->font_desc;
323 }
324 
325 /**
326  * fo_font_desc_set_font_description:
327  * @fo_font_desc: #FoFontDesc.
328  * @font_description: #PangoFontDescription.
329  *
330  * Set the language in @fo_font_desc.
331  **/
332 void
fo_font_desc_set_font_description(FoFontDesc * fo_font_desc,PangoFontDescription * desc)333 fo_font_desc_set_font_description (FoFontDesc *fo_font_desc,
334 				   PangoFontDescription *desc)
335 {
336   g_return_if_fail (fo_font_desc != NULL);
337   g_return_if_fail (desc != NULL);
338 
339   fo_font_desc->font_desc = desc;
340 }
341