1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
3 * Font code completely reworked for the Pango conversion
4 * Copyright (C) 2002 Cyrille Chepelov
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 #include <string.h> /* strlen */
30 #include <pango/pango.h>
32 #include <pango/pangoft2.h>
35 #include <gtk/gtk.h> /* just for gtk_get_default_language() */
36 #ifdef GDK_WINDOWING_WIN32
37 /* avoid namespace clashes caused by inclusion of windows.h */
38 #define Rectangle Win32Rectangle
39 #include <pango/pangowin32.h>
46 static PangoContext
* pango_context
= NULL
;
50 GObject parent_instance
;
52 PangoFontDescription
* pfd
;
53 /* mutable */ char* legacy_name
;
57 /* This is the global factor that says what zoom factor is 100%. It's
58 * normally 20.0 (and likely to stay that way). It is defined by how many
59 * pixels one cm is represented as.
61 static real global_zoom_factor
= 20.0;
64 /* For debugging: Sort families */
66 cmp_families (const void *a
, const void *b
)
68 const char *a_name
= pango_font_family_get_name (*(PangoFontFamily
**)a
);
69 const char *b_name
= pango_font_family_get_name (*(PangoFontFamily
**)b
);
71 return g_utf8_collate (a_name
, b_name
);
74 /* For debugging: List all font families */
78 PangoFontFamily
**families
;
82 pango_context_list_families(dia_font_get_context(), &families
, &nfamilies
);
83 qsort (families
, nfamilies
, sizeof (PangoFontFamily
*), cmp_families
);
84 for (i
= 0; i
< nfamilies
; i
++) {
85 puts(pango_font_family_get_name(families
[i
]));
92 dia_font_check_for_font(int font
) {
96 check
= dia_font_new_from_style(font
, 1.0);
97 loaded
= pango_context_load_font(dia_font_get_context(),
100 message_error(_("Can't load font %s.\n"), dia_font_get_family(check
));
105 dia_font_init(PangoContext
* pcontext
)
107 pango_context
= pcontext
;
108 /* We must have these three fonts! */
109 dia_font_check_for_font(DIA_FONT_SANS
);
110 dia_font_check_for_font(DIA_FONT_SERIF
);
111 dia_font_check_for_font(DIA_FONT_MONOSPACE
);
114 /* We might not need these anymore, when using FT2/Win32 fonts only */
115 static GList
*pango_contexts
;
118 dia_font_push_context(PangoContext
*pcontext
) {
119 pango_contexts
= g_list_prepend(pango_contexts
, pango_context
);
120 pango_context
= pcontext
;
121 pango_context_set_language (pango_context
, gtk_get_default_language ());
122 g_object_ref(pcontext
);
126 dia_font_pop_context() {
127 g_object_unref(pango_context
);
128 pango_context
= (PangoContext
*)pango_contexts
->data
;
129 pango_context_set_language (pango_context
, gtk_get_default_language ());
130 pango_contexts
= g_list_next(pango_contexts
);
134 dia_font_get_context() {
135 if (pango_context
== NULL
) {
137 /* This is suggested by new Pango (1.2.4+), but doesn't get us the
139 dia_font_push_context(pango_ft2_font_map_create_context(pango_ft2_font_map_new()));
141 dia_font_push_context(pango_ft2_get_context(75,75));
143 if (gdk_display_get_default ())
144 dia_font_push_context(gdk_pango_context_get());
146 # ifdef GDK_WINDOWING_WIN32
147 dia_font_push_context(pango_win32_get_context ());
149 g_warning ("dia_font_get_context() : not font context w/o display. Crashing soon.");
154 return pango_context
;
157 /* dia centimetres to pango device units */
159 dcm_to_pdu(real dcm
) { return dcm
* global_zoom_factor
* PANGO_SCALE
; }
160 /* pango device units to dia centimetres */
162 pdu_to_dcm(gint pdu
) { return (real
)pdu
/ (global_zoom_factor
* PANGO_SCALE
); }
164 static void dia_font_class_init(DiaFontClass
* class);
165 static void dia_font_finalize(GObject
* object
);
166 static void dia_font_init_instance(DiaFont
*);
169 dia_font_get_type (void)
171 static GType object_type
= 0;
174 static const GTypeInfo object_info
=
176 sizeof (DiaFontClass
),
177 (GBaseInitFunc
) NULL
,
178 (GBaseFinalizeFunc
) NULL
,
179 (GClassInitFunc
) dia_font_class_init
, /* class_init */
180 NULL
, /* class_finalize */
181 NULL
, /* class_data */
184 (GInstanceInitFunc
)dia_font_init_instance
186 object_type
= g_type_register_static (G_TYPE_OBJECT
,
192 static gpointer parent_class
;
195 dia_font_class_init(DiaFontClass
* klass
)
197 GObjectClass
* object_class
= G_OBJECT_CLASS(klass
);
198 parent_class
= g_type_class_peek_parent(klass
);
199 object_class
->finalize
= dia_font_finalize
;
203 dia_font_init_instance(DiaFont
* font
)
205 /*GObject *gobject = G_OBJECT(font); */
209 dia_font_new(const char *family
, DiaFontStyle style
, real height
)
211 DiaFont
* retval
= dia_font_new_from_style(style
, height
);
213 pango_font_description_set_family(retval
->pfd
,family
);
215 pango_context_load_font(dia_font_get_context(), retval
->pfd
);
221 dia_pfd_set_family(PangoFontDescription
* pfd
, DiaFontFamily fam
) {
224 pango_font_description_set_family(pfd
, "sans");
226 case DIA_FONT_SERIF
:
227 pango_font_description_set_family(pfd
, "serif");
229 case DIA_FONT_MONOSPACE
:
230 pango_font_description_set_family(pfd
, "monospace");
233 /* Pango does allow fonts without a name */
239 dia_pfd_set_weight(PangoFontDescription
* pfd
, DiaFontWeight fw
) {
241 case DIA_FONT_ULTRALIGHT
:
242 pango_font_description_set_weight(pfd
, PANGO_WEIGHT_ULTRALIGHT
);
244 case DIA_FONT_LIGHT
:
245 pango_font_description_set_weight(pfd
, PANGO_WEIGHT_LIGHT
);
247 case DIA_FONT_WEIGHT_NORMAL
:
248 pango_font_description_set_weight(pfd
, PANGO_WEIGHT_NORMAL
);
250 case DIA_FONT_MEDIUM
: /* Pango doesn't have this, but
251 'intermediate values are possible' */
252 pango_font_description_set_weight(pfd
, 500);
254 case DIA_FONT_DEMIBOLD
: /* Pango doesn't have this, ... */
255 pango_font_description_set_weight(pfd
, 600);
258 pango_font_description_set_weight(pfd
, PANGO_WEIGHT_BOLD
);
260 case DIA_FONT_ULTRABOLD
:
261 pango_font_description_set_weight(pfd
, PANGO_WEIGHT_ULTRABOLD
);
263 case DIA_FONT_HEAVY
:
264 pango_font_description_set_weight(pfd
, PANGO_WEIGHT_HEAVY
);
267 g_assert_not_reached();
272 dia_pfd_set_slant(PangoFontDescription
* pfd
, DiaFontSlant fo
) {
274 case DIA_FONT_NORMAL
:
275 pango_font_description_set_style(pfd
,PANGO_STYLE_NORMAL
);
277 case DIA_FONT_OBLIQUE
:
278 pango_font_description_set_style(pfd
,PANGO_STYLE_OBLIQUE
);
280 case DIA_FONT_ITALIC
:
281 pango_font_description_set_style(pfd
,PANGO_STYLE_ITALIC
);
284 g_assert_not_reached();
288 static void dia_pfd_set_size(PangoFontDescription
* pfd
, real height
)
289 { /* inline candidate... */
290 pango_font_description_set_size(pfd
, dcm_to_pdu(height
) );
295 dia_font_new_from_style(DiaFontStyle style
, real height
)
298 /* in the future we could establish Dia's own default font
299 * matching to be as (font-)system independent as possible.
300 * For now fall back to Pangos configuration --hb
302 PangoFontDescription
* pfd
= pango_font_description_new();
303 dia_pfd_set_family(pfd
,DIA_FONT_STYLE_GET_FAMILY(style
));
304 dia_pfd_set_weight(pfd
,DIA_FONT_STYLE_GET_WEIGHT(style
));
305 dia_pfd_set_slant(pfd
,DIA_FONT_STYLE_GET_SLANT(style
));
306 dia_pfd_set_size(pfd
,height
);
308 retval
= DIA_FONT(g_object_new(DIA_TYPE_FONT
, NULL
));
311 retval
->legacy_name
= NULL
;
315 DiaFont
* dia_font_copy(const DiaFont
* font
)
317 if (!font
) return NULL
;
318 return dia_font_new(dia_font_get_family(font
),
319 dia_font_get_style(font
),
320 dia_font_get_height(font
));
324 dia_font_finalize(GObject
* object
)
327 font
= DIA_FONT(object
);
328 if (font
->pfd
) pango_font_description_free(font
->pfd
);
329 G_OBJECT_CLASS(parent_class
)->finalize(object
);
332 DiaFont
* dia_font_ref(DiaFont
* font
)
334 g_object_ref(G_OBJECT(font
));
338 void dia_font_unref(DiaFont
* font
)
340 g_object_unref(G_OBJECT(font
));
344 dia_font_get_style(const DiaFont
* font
)
348 static int weight_map
[] = {
349 DIA_FONT_ULTRALIGHT
, DIA_FONT_LIGHT
,
350 DIA_FONT_WEIGHT_NORMAL
, /* intentionaly ==0 */
351 DIA_FONT_MEDIUM
, DIA_FONT_DEMIBOLD
, /* not yet in Pango */
352 DIA_FONT_BOLD
, DIA_FONT_ULTRABOLD
, DIA_FONT_HEAVY
355 PangoStyle pango_style
= pango_font_description_get_style(font
->pfd
);
356 PangoWeight pango_weight
= pango_font_description_get_weight(font
->pfd
);
358 g_assert(PANGO_WEIGHT_ULTRALIGHT
<= pango_weight
&& pango_weight
<= PANGO_WEIGHT_HEAVY
);
359 g_assert(PANGO_WEIGHT_ULTRALIGHT
== 200);
360 g_assert(PANGO_WEIGHT_NORMAL
== 400);
361 g_assert(PANGO_WEIGHT_BOLD
== 700);
363 style
= weight_map
[(pango_weight
- PANGO_WEIGHT_ULTRALIGHT
) / 100];
364 style
|= (pango_style
<< 2);
370 dia_font_get_family(const DiaFont
* font
)
372 return pango_font_description_get_family(font
->pfd
);
375 G_CONST_RETURN PangoFontDescription
*
376 dia_font_get_description(const DiaFont
* font
)
382 dia_font_get_height(const DiaFont
* font
)
384 return pdu_to_dcm(pango_font_description_get_size(font
->pfd
));
388 dia_font_set_height(DiaFont
* font
, real height
)
390 pango_font_description_set_size(font
->pfd
, dcm_to_pdu(height
));
395 dia_font_get_psfontname(const DiaFont
*font
)
397 /* FIXME: this will very likely not work ! */
398 return dia_font_get_legacy_name(font
);
401 void dia_font_set_any_family(DiaFont
* font
, const char* family
)
403 g_assert(font
!= NULL
);
404 pango_font_description_set_family(font
->pfd
, family
);
405 if (font
->legacy_name
) {
406 g_free(font
->legacy_name
);
407 font
->legacy_name
= NULL
;
411 void dia_font_set_family(DiaFont
* font
, DiaFontFamily family
)
413 g_assert(font
!= NULL
);
414 dia_pfd_set_family(font
->pfd
,family
);
415 if (font
->legacy_name
) {
416 g_free(font
->legacy_name
);
417 font
->legacy_name
= NULL
;
421 void dia_font_set_weight(DiaFont
* font
, DiaFontWeight weight
)
423 g_assert(font
!= NULL
);
424 dia_pfd_set_weight(font
->pfd
,weight
);
427 void dia_font_set_slant(DiaFont
* font
, DiaFontSlant slant
)
429 g_assert(font
!= NULL
);
430 dia_pfd_set_slant(font
->pfd
,slant
);
434 struct weight_name
{ DiaFontWeight fw
; const char *name
; };
435 static const struct weight_name weight_names
[] = {
436 {DIA_FONT_ULTRALIGHT
, "200"},
437 {DIA_FONT_LIGHT
,"300"},
438 {DIA_FONT_WEIGHT_NORMAL
,"normal"},
439 {DIA_FONT_WEIGHT_NORMAL
,"400"},
440 {DIA_FONT_MEDIUM
, "500"},
441 {DIA_FONT_DEMIBOLD
, "600"},
442 {DIA_FONT_BOLD
, "700"},
443 {DIA_FONT_ULTRABOLD
, "800"},
444 {DIA_FONT_HEAVY
, "900"},
447 G_CONST_RETURN
char *dia_font_get_weight_string(const DiaFont
* font
)
449 const struct weight_name
* p
;
450 DiaFontWeight fw
= DIA_FONT_STYLE_GET_WEIGHT(dia_font_get_style(font
));
452 for (p
= weight_names
; p
->name
!= NULL
; ++p
) {
453 if (p
->fw
== fw
) return p
->name
;
458 void dia_font_set_weight_from_string(DiaFont
* font
, const char* weight
) {
459 DiaFontWeight fw
= DIA_FONT_WEIGHT_NORMAL
;
460 const struct weight_name
* p
;
462 for (p
= weight_names
; p
->name
!= NULL
; ++p
) {
463 if (0 == strncmp(weight
,p
->name
,8)) {
469 dia_font_set_weight(font
,fw
);
473 struct slant_name
{ DiaFontSlant fo
; const char *name
; };
474 static const struct slant_name slant_names
[] = {
475 { DIA_FONT_NORMAL
, "normal"},
476 { DIA_FONT_OBLIQUE
, "oblique"},
477 { DIA_FONT_ITALIC
, "italic"},
480 G_CONST_RETURN
char *
481 dia_font_get_slant_string(const DiaFont
* font
)
483 const struct slant_name
* p
;
485 DIA_FONT_STYLE_GET_SLANT(dia_font_get_style(font
));
487 for (p
= slant_names
; p
->name
!= NULL
; ++p
) {
488 if (p
->fo
== fo
) return p
->name
;
493 void dia_font_set_slant_from_string(DiaFont
* font
, const char* obli
) {
494 DiaFontSlant fo
= DIA_FONT_NORMAL
;
495 const struct slant_name
* p
;
497 DiaFontStyle old_style
;
499 old_style
= dia_font_get_style(font
);
500 old_fo
= DIA_FONT_STYLE_GET_SLANT(old_style
);
502 for (p
= slant_names
; p
->name
!= NULL
; ++p
) {
503 if (0 == strncmp(obli
,p
->name
,8)) {
508 dia_font_set_slant(font
,fo
);
512 /* ************************************************************************ */
513 /* Non-scaled versions of the utility routines */
514 /* ************************************************************************ */
517 dia_font_string_width(const char* string
, DiaFont
*font
, real height
)
519 return dia_font_scaled_string_width(string
,font
,height
,global_zoom_factor
);
523 dia_font_ascent(const char* string
, DiaFont
* font
, real height
)
525 return dia_font_scaled_ascent(string
,font
,height
,global_zoom_factor
);
528 real
dia_font_descent(const char* string
, DiaFont
* font
, real height
)
530 return dia_font_scaled_descent(string
,font
,height
,global_zoom_factor
);
535 dia_font_build_layout(const char* string
, DiaFont
* font
, real height
)
539 PangoAttribute
* attr
;
544 dia_font_set_height(font
, height
);
547 /* This could should account for DPI, but it doesn't do right. Grrr...
549 GdkScreen *screen = gdk_screen_get_default();
550 real dpi = gdk_screen_get_width(screen)/
551 (gdk_screen_get_width_mm(screen)/25.4);
552 printf("height = %f, dpi = %f, new height = %f\n",
553 height, dpi, height * (dpi/100));
558 layout
= pango_layout_new(dia_font_get_context());
560 length
= string
? strlen(string
) : 0;
561 pango_layout_set_text(layout
, string
, length
);
563 list
= pango_attr_list_new();
564 desc
= g_utf8_strdown(pango_font_description_get_family(font
->pfd
), -1);
565 pango_font_description_set_family(font
->pfd
, desc
);
567 attr
= pango_attr_font_desc_new(font
->pfd
);
568 attr
->start_index
= 0;
569 attr
->end_index
= length
;
570 pango_attr_list_insert(list
,attr
); /* eats attr */
572 pango_layout_set_attributes(layout
,list
);
573 pango_attr_list_unref(list
);
575 pango_layout_set_indent(layout
,0);
576 pango_layout_set_justify(layout
,FALSE
);
577 pango_layout_set_alignment(layout
,PANGO_ALIGN_LEFT
);
582 /* ************************************************************************ */
583 /* scaled versions of the utility routines */
584 /* ************************************************************************ */
587 dia_font_set_nominal_zoom_factor(real size_one
)
588 { global_zoom_factor
= size_one
; }
593 dia_font_scaled_string_width(const char* string
, DiaFont
*font
, real height
,
600 if (string
== NULL
|| string
[0] == '\0') {
604 layout
= dia_font_scaled_build_layout(string
, font
, height
, zoom_factor
);
605 pango_layout_get_size(layout
,&lw
,&lh
);
606 g_object_unref(G_OBJECT(layout
));
608 result
= pdu_to_dcm(lw
);
609 /* Scale the result back for the zoom factor */
610 result
/= (zoom_factor
/global_zoom_factor
);
615 dia_font_vertical_extents(const char* string
, DiaFont
* font
,
616 real height
, real zoom_factor
,
618 real
* top
, real
* baseline
, real
* bottom
)
620 PangoRectangle ink_rect
,logical_rect
;
622 PangoLayoutIter
* iter
;
625 if (string
== NULL
|| string
[0] == '\0') {
629 layout
= dia_font_scaled_build_layout(string
, font
,
630 height
, zoom_factor
);
631 iter
= pango_layout_get_iter(layout
);
632 for (i
= 0; i
< line_no
; ++i
) {
633 if (!pango_layout_iter_next_line(iter
)) {
634 pango_layout_iter_free(iter
);
635 g_object_unref(G_OBJECT(layout
));
640 pango_layout_iter_get_line_extents(iter
,&ink_rect
,&logical_rect
);
642 *top
= pdu_to_dcm(logical_rect
.y
);
643 *bottom
= pdu_to_dcm(logical_rect
.y
+ logical_rect
.height
);
644 *baseline
= pdu_to_dcm(pango_layout_iter_get_baseline(iter
));
646 pango_layout_iter_free(iter
);
647 g_object_unref(G_OBJECT(layout
));
654 dia_font_scaled_ascent(const char* string
, DiaFont
* font
, real height
,
657 real top
,bline
,bottom
;
658 if (!string
|| string
[0] == '\0') {
659 /* This hack won't work for fonts that don't cover ASCII */
660 dia_font_vertical_extents("XjgM149",font
,height
,zoom_factor
,
661 0,&top
,&bline
,&bottom
);
663 dia_font_vertical_extents(string
,font
,height
,zoom_factor
,
664 0,&top
,&bline
,&bottom
);
666 return (bline
-top
)/(zoom_factor
/global_zoom_factor
);
669 real
dia_font_scaled_descent(const char* string
, DiaFont
* font
,
670 real height
, real zoom_factor
)
672 real top
,bline
,bottom
;
674 if (!string
|| string
[0] == '\0') {
675 /* This hack won't work for fonts that don't cover ASCII */
676 dia_font_vertical_extents("XjgM149",font
,height
,zoom_factor
,
677 0,&top
,&bline
,&bottom
);
679 dia_font_vertical_extents(string
,font
,height
,zoom_factor
,
680 0,&top
,&bline
,&bottom
);
682 return (bottom
-bline
)/(zoom_factor
/global_zoom_factor
);
685 /** Find the offsets of the individual letters in the iter and place them
687 * This currently assumes only one run per iter, which is all we can input.
688 * @param iter The PangoLayoutIter to count characters in.
689 * @param offsets The place to return the offsets
690 * @param n_offsets The place to return the number of offsets
693 get_string_offsets(PangoLayoutIter
*iter
, real
** offsets
, int* n_offsets
)
696 PangoLayoutLine
* line
= pango_layout_iter_get_line(iter
);
697 PangoGlyphItem
* item
= (PangoGlyphItem
*)line
->runs
->data
;
698 PangoGlyphString
* string
= item
->glyphs
;
700 *n_offsets
= string
->num_glyphs
;
701 *offsets
= g_new(real
, *n_offsets
);
703 for (i
= 0; i
< string
->num_glyphs
; i
++) {
704 PangoGlyphGeometry geom
= string
->glyphs
[i
].geometry
;
706 (*offsets
)[i
] = pdu_to_dcm(geom
.width
) / 20;
710 /** Get size information for the given string, font and height.
712 * @returns an array of offsets of the individual glyphs in the layout.
715 dia_font_get_sizes(const char* string
, DiaFont
*font
, real height
,
716 real
*width
, real
*ascent
, real
*descent
, int *n_offsets
)
720 PangoLayoutIter
* iter
;
721 real top
, bline
, bottom
;
722 gchar
* non_empty_string
;
723 PangoRectangle ink_rect
,logical_rect
;
727 if (string
== NULL
|| string
[0] == '\0') {
728 non_empty_string
= "XjgM149";
730 non_empty_string
= string
;
732 layout
= dia_font_build_layout(non_empty_string
, font
, height
* 20);
734 /* Only one line here */
735 iter
= pango_layout_get_iter(layout
);
737 pango_layout_iter_get_line_extents(iter
, &ink_rect
, &logical_rect
);
739 top
= pdu_to_dcm(logical_rect
.y
) / 20;
740 bottom
= pdu_to_dcm(logical_rect
.y
+ logical_rect
.height
) / 20;
741 bline
= pdu_to_dcm(pango_layout_iter_get_baseline(iter
)) / 20;
743 get_string_offsets(iter
, &offsets
, n_offsets
);
745 pango_layout_iter_free(iter
);
746 g_object_unref(G_OBJECT(layout
));
749 *descent
= bottom
-bline
;
750 if (non_empty_string
!= string
) {
753 *width
= pdu_to_dcm(logical_rect
.width
) / 20;
759 dia_font_scaled_build_layout(const char* string
, DiaFont
* font
,
760 real height
, real zoom_factor
)
762 DiaFont
* altered_font
;
765 real target_zoomed_width
;
767 real altered_scaling
;
770 scaling
= zoom_factor
/ global_zoom_factor
;
771 if (fabs(1.0 - scaling
) < 1E-7) {
772 return dia_font_build_layout(string
,font
,height
);
775 nozoom_width
= dia_font_string_width(string
,font
,height
);
776 target_zoomed_width
= nozoom_width
* scaling
;
778 /* First try: no tweaks. */
779 real_width
= dia_font_string_width(string
,font
, height
* scaling
);
780 if (real_width
<= target_zoomed_width
) {
781 return dia_font_build_layout(string
,font
,height
*scaling
);
784 altered_font
= dia_font_copy(font
);
786 /* Last try. Using the "reduce overall size" strategy. */
787 for (altered_scaling
= scaling
;
788 altered_scaling
> (scaling
/ 2);
789 altered_scaling
*= (target_zoomed_width
/real_width
>0.98?0.98:
790 target_zoomed_width
/real_width
) ) {
791 real_width
= dia_font_string_width(string
,font
,
792 height
* altered_scaling
);
794 if (real_width
<= target_zoomed_width
) {
795 layout
= dia_font_build_layout(string
,altered_font
,
796 height
*altered_scaling
);
797 dia_font_unref(altered_font
);
802 /* Everything has failed. Returning non-tweaked variant. */
803 g_warning("Failed to appropriately tweak zoomed font for zoom factor %f.", zoom_factor
);
804 dia_font_unref(altered_font
);
805 return dia_font_build_layout(string
,font
,height
*scaling
);
809 * Compatibility with older files out of pre Pango Time.
810 * Make old files look as similar as possible
811 * List should be kept alphabetically sorted by oldname, in case of
812 * duplicates the one with the preferred newname comes first.
814 * FIXME: DIA_FONT_FAMILY_ANY in the list below does mean noone knows better
816 static struct _legacy_font
{
819 DiaFontStyle style
; /* the DIA_FONT_FAMILY() is used as falback only */
821 { "AvantGarde-Book", "AvantGarde", DIA_FONT_SERIF
},
822 { "AvantGarde-BookOblique", "AvantGarde", DIA_FONT_SERIF
| DIA_FONT_OBLIQUE
},
823 { "AvantGarde-Demi", "AvantGarde", DIA_FONT_SERIF
| DIA_FONT_DEMIBOLD
},
824 { "AvantGarde-DemiOblique", "AvantGarde", DIA_FONT_SERIF
| DIA_FONT_OBLIQUE
| DIA_FONT_DEMIBOLD
},
825 { "Batang", "Batang", DIA_FONT_FAMILY_ANY
},
826 { "Bookman-Demi", "Bookman Old Style", DIA_FONT_SERIF
| DIA_FONT_DEMIBOLD
},
827 { "Bookman-DemiItalic", "Bookman Old Style", DIA_FONT_SERIF
| DIA_FONT_DEMIBOLD
| DIA_FONT_ITALIC
},
828 { "Bookman-Light", "Bookman Old Style", DIA_FONT_SERIF
| DIA_FONT_LIGHT
},
829 { "Bookman-LightItalic", "Bookman Old Style", DIA_FONT_SERIF
| DIA_FONT_LIGHT
| DIA_FONT_ITALIC
},
830 { "BousungEG-Light-GB", "BousungEG-Light-GB", DIA_FONT_FAMILY_ANY
},
831 { "Courier", "monospace", DIA_FONT_MONOSPACE
},
832 { "Courier", "Courier New", DIA_FONT_MONOSPACE
},
833 { "Courier-Bold", "monospace", DIA_FONT_MONOSPACE
| DIA_FONT_BOLD
},
834 { "Courier-Bold", "Courier New", DIA_FONT_MONOSPACE
| DIA_FONT_BOLD
},
835 { "Courier-BoldOblique", "monospace", DIA_FONT_MONOSPACE
| DIA_FONT_ITALIC
| DIA_FONT_BOLD
},
836 { "Courier-BoldOblique", "Courier New", DIA_FONT_MONOSPACE
| DIA_FONT_ITALIC
| DIA_FONT_BOLD
},
837 { "Courier-Oblique", "monospace", DIA_FONT_MONOSPACE
| DIA_FONT_ITALIC
},
838 { "Courier-Oblique", "Courier New", DIA_FONT_MONOSPACE
| DIA_FONT_ITALIC
},
839 { "Dotum", "Dotum", DIA_FONT_FAMILY_ANY
},
840 { "GBZenKai-Medium", "GBZenKai-Medium", DIA_FONT_FAMILY_ANY
},
841 { "GothicBBB-Medium", "GothicBBB-Medium", DIA_FONT_FAMILY_ANY
},
842 { "Gulim", "Gulim", DIA_FONT_FAMILY_ANY
},
843 { "Headline", "Headline", DIA_FONT_FAMILY_ANY
},
844 { "Helvetica", "sans", DIA_FONT_SANS
},
845 { "Helvetica", "Arial", DIA_FONT_SANS
},
846 { "Helvetica-Bold", "sans", DIA_FONT_SANS
| DIA_FONT_BOLD
},
847 { "Helvetica-Bold", "Arial", DIA_FONT_SANS
| DIA_FONT_BOLD
},
848 { "Helvetica-BoldOblique", "sans", DIA_FONT_SANS
| DIA_FONT_BOLD
| DIA_FONT_ITALIC
},
849 { "Helvetica-BoldOblique", "Arial", DIA_FONT_SANS
| DIA_FONT_BOLD
| DIA_FONT_ITALIC
},
850 { "Helvetica-Narrow", "Arial Narrow", DIA_FONT_SANS
| DIA_FONT_MEDIUM
},
851 { "Helvetica-Narrow-Bold", "Arial Narrow", DIA_FONT_SANS
| DIA_FONT_DEMIBOLD
},
852 { "Helvetica-Narrow-BoldOblique", "Arial Narrow", DIA_FONT_SANS
| DIA_FONT_MEDIUM
| DIA_FONT_OBLIQUE
},
853 { "Helvetica-Narrow-Oblique", "Arial Narrow", DIA_FONT_SANS
| DIA_FONT_MEDIUM
| DIA_FONT_OBLIQUE
},
854 { "Helvetica-Oblique", "sans", DIA_FONT_SANS
| DIA_FONT_ITALIC
},
855 { "Helvetica-Oblique", "Arial", DIA_FONT_SANS
| DIA_FONT_ITALIC
},
856 { "MOESung-Medium", "MOESung-Medium", DIA_FONT_FAMILY_ANY
},
857 { "NewCenturySchoolbook-Bold", "Century Schoolbook SWA", DIA_FONT_SERIF
| DIA_FONT_BOLD
},
858 { "NewCenturySchoolbook-BoldItalic", "Century Schoolbook SWA", DIA_FONT_SERIF
| DIA_FONT_BOLD
| DIA_FONT_ITALIC
},
859 { "NewCenturySchoolbook-Italic", "Century Schoolbook SWA", DIA_FONT_SERIF
| DIA_FONT_ITALIC
},
860 { "NewCenturySchoolbook-Roman", "Century Schoolbook SWA", DIA_FONT_SERIF
},
861 { "Palatino-Bold", "Palatino", DIA_FONT_FAMILY_ANY
| DIA_FONT_BOLD
},
862 { "Palatino-BoldItalic", "Palatino", DIA_FONT_FAMILY_ANY
| DIA_FONT_BOLD
| DIA_FONT_ITALIC
},
863 { "Palatino-Italic", "Palatino", DIA_FONT_FAMILY_ANY
| DIA_FONT_ITALIC
},
864 { "Palatino-Roman", "Palatino", DIA_FONT_FAMILY_ANY
},
865 { "Ryumin-Light", "Ryumin", DIA_FONT_FAMILY_ANY
| DIA_FONT_LIGHT
},
866 { "ShanHeiSun-Light", "ShanHeiSun", DIA_FONT_FAMILY_ANY
| DIA_FONT_LIGHT
},
867 { "Song-Medium", "Song-Medium", DIA_FONT_FAMILY_ANY
| DIA_FONT_MEDIUM
},
868 { "Symbol", "Symbol", DIA_FONT_SANS
| DIA_FONT_MEDIUM
},
869 { "Times-Bold", "serif", DIA_FONT_SERIF
| DIA_FONT_BOLD
},
870 { "Times-Bold", "Times New Roman", DIA_FONT_SERIF
| DIA_FONT_BOLD
},
871 { "Times-BoldItalic", "serif", DIA_FONT_SERIF
| DIA_FONT_ITALIC
| DIA_FONT_BOLD
},
872 { "Times-BoldItalic", "Times New Roman", DIA_FONT_SERIF
| DIA_FONT_ITALIC
| DIA_FONT_BOLD
},
873 { "Times-Italic", "serif", DIA_FONT_SERIF
| DIA_FONT_ITALIC
},
874 { "Times-Italic", "Times New Roman", DIA_FONT_SERIF
| DIA_FONT_ITALIC
},
875 { "Times-Roman", "serif", DIA_FONT_SERIF
},
876 { "Times-Roman", "Times New Roman", DIA_FONT_SERIF
},
877 { "ZapfChancery-MediumItalic", "Zapf Calligraphic 801 SWA", DIA_FONT_SERIF
| DIA_FONT_MEDIUM
},
878 { "ZapfDingbats", "Zapf Calligraphic 801 SWA", DIA_FONT_SERIF
},
879 { "ZenKai-Medium", "ZenKai", DIA_FONT_FAMILY_ANY
| DIA_FONT_MEDIUM
},
884 * Given a legacy name as stored until Dia-0.90 construct
885 * a new DiaFont which is as similar as possible
888 dia_font_new_from_legacy_name(const char* name
)
890 /* do NOT translate anything here !!! */
892 struct _legacy_font
* found
= NULL
;
896 for (i
= 0; i
< G_N_ELEMENTS(legacy_fonts
); i
++) {
897 if (!strcmp(name
, legacy_fonts
[i
].oldname
)) {
898 found
= &legacy_fonts
[i
];
903 retval
= dia_font_new (found
->newname
, found
->style
, height
);
904 retval
->legacy_name
= found
->oldname
;
906 /* We tried our best, let Pango complain */
907 retval
= dia_font_new (name
, DIA_FONT_WEIGHT_NORMAL
, height
);
908 retval
->legacy_name
= NULL
;
915 dia_font_get_legacy_name(const DiaFont
*font
)
917 const char* matched_name
= NULL
;
922 /* if we have loaded it from an old file, use the old name */
923 if (font
->legacy_name
)
924 return font
->legacy_name
;
926 family
= dia_font_get_family (font
);
927 style
= dia_font_get_style (font
);
928 for (i
= 0; i
< G_N_ELEMENTS(legacy_fonts
); i
++) {
929 if (0 == g_strcasecmp (legacy_fonts
[i
].newname
, family
)) {
930 /* match weight and slant */
931 DiaFontStyle st
= legacy_fonts
[i
].style
;
932 if ((DIA_FONT_STYLE_GET_SLANT(style
) | DIA_FONT_STYLE_GET_WEIGHT(style
))
933 == (DIA_FONT_STYLE_GET_SLANT(st
) | DIA_FONT_STYLE_GET_WEIGHT(st
))) {
934 return legacy_fonts
[i
].oldname
; /* exact match */
935 } else if (0 == (DIA_FONT_STYLE_GET_SLANT(st
) | DIA_FONT_STYLE_GET_WEIGHT(st
))) {
936 matched_name
= legacy_fonts
[i
].oldname
;
937 /* 'unmodified' font, continue matching */
941 return matched_name
? matched_name
: "Courier";