00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 #include "config.h"
00019 #endif
00020
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include "gvplugin_textlayout.h"
00024
00025 #ifdef HAVE_PANGOCAIRO
00026 #include <pango/pangocairo.h>
00027 #ifdef HAVE_FONTCONFIG
00028 #include <pango/pangofc-font.h>
00029 #endif
00030
00031 static void pango_free_layout (void *layout)
00032 {
00033 g_object_unref((PangoLayout*)layout);
00034 }
00035
00036 #define FONT_DPI 96.
00037
00038 extern char* psfontResolve (PostscriptAlias* pa);
00039
00040 static boolean pango_textlayout(textpara_t * para, char **fontpath)
00041 {
00042 static char buf[1024];
00043 static PangoFontMap *fontmap;
00044 static PangoContext *context;
00045 static PangoFontDescription *desc;
00046 static char *fontname;
00047 static double fontsize;
00048 char *fnt, *psfnt = NULL;
00049 PangoLayout *layout;
00050 PangoRectangle logical_rect;
00051 PangoLayoutIter* iter;
00052 cairo_font_options_t* options;
00053 #ifdef ENABLE_PANGO_MARKUP
00054 PangoAttrList *attrs;
00055 GError *error = NULL;
00056 #endif
00057 char *text;
00058 double textlayout_scale;
00059
00060 if (!context) {
00061 fontmap = pango_cairo_font_map_get_default();
00062 context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
00063 options=cairo_font_options_create();
00064 cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY);
00065 cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL);
00066 cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON);
00067 cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR);
00068 pango_cairo_context_set_font_options(context, options);
00069
00070 g_object_unref(fontmap);
00071 }
00072
00073 if (!fontname || strcmp(fontname, para->fontname) != 0 || fontsize != para->fontsize) {
00074 fontname = para->fontname;
00075 fontsize = para->fontsize;
00076 pango_font_description_free (desc);
00077
00078 if (para->postscript_alias) {
00079 psfnt = fnt = psfontResolve (para->postscript_alias);
00080 }
00081 else
00082 fnt = fontname;
00083
00084 desc = pango_font_description_from_string(fnt);
00085
00086 pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE));
00087
00088 if (fontpath) {
00089 PangoFont *font;
00090
00091 font = pango_font_map_load_font(fontmap, context, desc);
00092
00093 buf[0] = '\0';
00094 if (psfnt)
00095 strcat(buf, "(ps) ");
00096 #ifdef HAVE_FONTCONFIG
00097 {
00098 FT_Face face;
00099 PangoFcFont *fcfont;
00100 FT_Stream stream;
00101 FT_StreamDesc streamdesc;
00102 fcfont = PANGO_FC_FONT(font);
00103 if (fcfont) {
00104 face = pango_fc_font_lock_face(fcfont);
00105 if (face) {
00106 strcat(buf, "\"");
00107 strcat(buf, face->family_name);
00108 strcat(buf, ", ");
00109 strcat(buf, face->style_name);
00110 strcat(buf, "\" ");
00111
00112 stream = face->stream;
00113 if (stream) {
00114 streamdesc = stream->pathname;
00115 if (streamdesc.pointer)
00116 strcat(buf, (char*)streamdesc.pointer);
00117 else
00118 strcat(buf, "*no pathname available*");
00119 }
00120 else
00121 strcat(buf, "*no stream available*");
00122 }
00123 pango_fc_font_unlock_face(fcfont);
00124 }
00125 else
00126 strcat(buf, "*not using fontconfig*");
00127 }
00128 #else
00129 {
00130 PangoFontDescription *tdesc;
00131 char *tfont;
00132
00133 tdesc = pango_font_describe(font);
00134 tfont = pango_font_description_to_string(tdesc);
00135 strcat(buf, "\"");
00136 strcat(buf, tfont);
00137 strcat(buf, "\" ");
00138 g_free(tfont);
00139 }
00140 #endif
00141 *fontpath = buf;
00142 }
00143 }
00144
00145 #ifdef ENABLE_PANGO_MARKUP
00146 if (! pango_parse_markup (para->str, -1, 0, &attrs, &text, NULL, &error))
00147 die(error->message);
00148 #else
00149 text = para->str;
00150 #endif
00151
00152 layout = pango_layout_new (context);
00153 para->layout = (void *)layout;
00154 para->free_layout = pango_free_layout;
00155
00156 pango_layout_set_text (layout, text, -1);
00157 pango_layout_set_font_description (layout, desc);
00158 #ifdef ENABLE_PANGO_MARKUP
00159 pango_layout_set_attributes (layout, attrs);
00160 #endif
00161
00162 pango_layout_get_extents (layout, NULL, &logical_rect);
00163
00164
00165 if (logical_rect.width == 0)
00166 logical_rect.height = 0;
00167
00168 textlayout_scale = POINTS_PER_INCH / (FONT_DPI * PANGO_SCALE);
00169 para->width = ROUND(logical_rect.width * textlayout_scale);
00170 para->height = ROUND(logical_rect.height * textlayout_scale);
00171
00172
00173 iter = pango_layout_get_iter (layout);
00174 para->yoffset_layout = pango_layout_iter_get_baseline (iter) * textlayout_scale;
00175
00176
00177 para->yoffset_centerline = 0.1 * para->fontsize;
00178
00179 pango_layout_iter_free (iter);
00180 if (logical_rect.width == 0)
00181 return FALSE;
00182 return TRUE;
00183 }
00184
00185 static gvtextlayout_engine_t pango_textlayout_engine = {
00186 pango_textlayout,
00187 };
00188 #endif
00189
00190 gvplugin_installed_t gvtextlayout_pango_types[] = {
00191 #ifdef HAVE_PANGOCAIRO
00192 {0, "textlayout", 10, &pango_textlayout_engine, NULL},
00193 #endif
00194 {0, NULL, 0, NULL, NULL}
00195 };