Pango programming guide

原创 2004年08月04日 07:16:00

If you're using any kind of non-default fonts, you'll want to convert your code to use the new PangoFontDescription rather than GdkFont. PangoFontDescription is much, much easier to use; to load a GdkFont you had to specify an awkward X font description string, and the resulting GdkFont was specific to a certain locale; it wouldn't work for all languages. Moreover, there were no fonts you could choose that everyone using your application was guaranteed to have, so a call to gdk_font_load() could always fail.

PangoFontDescription is much higher-level. The exact font technology used by GTK+ varies according to GDK target and how GTK+ was compiled; underneath Pango, the real implementation could be Win32 fonts, XRender fonts, traditional X fonts, TrueType fonts, or even a mixture. Pango can even assemble a collection of locale-specific fonts and use those to emulate a single Unicode font. Programmers don't have to worry about this; they specify high-level font details such as "Sans Italic 12".

A PangoFontDescription has a stringified form, described in the Pango documentation. "Sans Italic 12" is an example of such a string. The easiest way to obtain a PangoFontDescription is to call pango_font_description_from_string(). The font families "Sans", "Monospace", and "Serif" are guaranteed to exist on all GTK+ installations; these will never fail to load.

If you were using the font field in GtkStyle to change the font for a widget, you'll need to use the new font_desc field instead. However, when converting your code from GdkFont, ask yourself if setting style->font remains the easiest thing to do; gtk_label_new_from_markup() is a handy alternative provided for GtkLabel. You can pass in a string marked up with HTML-like tags affecting text attributes such as color, text size, font family, and so on. The Pango documentation describes all the tags you can use. If you do still want to modify the style, probably you can use the new gtk_widget_modify_font() function instead of fooling with styles manually. gtk_widget_modify_font() works properly when the theme changes, and is easier to use.

If you were using gdk_draw_string(), gdk_draw_text(), gtk_paint_string(), or variants thereof, you'll want to rework your code to use PangoLayout. A PangoLayout represents a paragraph of text to be rendered to the screen. With English or European text, to render a paragraph, you just break on spaces and draw each line one font height below the previous line. When you start to handle languages such as Arabic, Hindi, Japanese, Hebrew, Thai, or Korean, however, this is wrong; it simply won't work properly. Pango handles the details with PangoLayout. To render a paragraph of text, create a PangoLayout for that text, then call gdk_draw_layout or gtk_paint_layout(). To create your layout, call gtk_widget_create_pango_layout() on the widget you intend to draw on.

While you'll usually just create a layout and draw it, for more complex cases PangoLayout has a lot of useful features; it has text attributes, and you can use the HTML-like Pango markup language mentioned earlier as a convenient way to set those attributes. (The less-convenient way uses PangoAttrList directly.) PangoLayout can also handle cursors, conversion from pixel locations to text positions, and that kind of thing.

When asking for text metrics, such as the size of a PangoLayout, you'll notice that all Pango objects have a "logical size" and an "ink size." The logical size corresponds to the font metrics (ascent and descent), and should be used to position text. The logical size for a line of text will change if you add a new character that's larger than the existing characters. The ink size of some text describes the actual pixels covered by the font glyphs, so for example capital letters have a larger ink size than lowercase, and letters with "descenders" such as lowercase "y", "g", "p" have a larger ink size than letters without. Usually you don't need the ink size. Logical size should be used in widget size requests, and in any other case where you're positioning text.

Pango sizes are specified in "Pango units," which are converted to and from device units (e.g. pixels) using the PANGO_SCALE constant. There are PANGO_SCALE units per pixel.

If your application does anything complicated with text, such as text editing, you'll want to investigate Pango in more depth. Some considerations and definitions to keep in mind:

  • Logical and visual direction do not correspond. Logical direction is the sequence of characters in a string; iterating over a string moves through it logically. Visual direction is the sequence of font glyphs on the user's monitor. Overall text direction can be right-to-left instead of left-to-right; also, individual characters can be "reordered" on a smaller scale, so that glyphs representing characters are not in the same sequence as the characters themselves.

  • Glyphs do not correspond to characters. That is, multiple Unicode characters can be displayed as a single font glyph on the screen. A cluster is a set of characters represented by a single glyph. (Glyphs are the graphical characters making up a font.)

  • The process of converting a string of characters into a string of glyphs is called shaping. The low-level Pango function pango_shape() performs this operation -- PangoLayout does shaping for you, so typically you don't need to think about it.

  • Word, line, sentence, and paragraph breaks do not necessarily follow English rules. Some languages are written with no spaces, for example, so you can't use spaces to split up words. Line break rules depend on the language. Paragraphs can be broken by the newline/linefeed ('/n') character, by carriage return ('/r'), by a sequence of carriage return and line feed, or by a special Unicode paragraph separator character. You can obtain text boundary information for a paragraph of text with the functions pango_break(), pango_get_log_attrs(), and pango_find_paragraph_boundary().

  • It's not possible to put the cursor (caret, insertion mark) at all character positions. Some characters "combine" into a single logical unit, and the cursor can't go between the combined characters. A group of combined characters is called a grapheme, that is, a logical unit of writing. pango_break() and friends report valid cursor positions along with other text boundary information.

The PangoLayout structure represents and entire paragraph of text. It is initialized with a PangoContext, UTF-8 string and set of attributes for that string. Once that is done, the set of formatted lines can be extracted from the object, the layout can be rendered, and conversion between logical character positions within the layout's text, and the physical position of the resulting glyphs can be made.

There are also a number of parameters to adjust the formatting of a PangoLayout, which are illustrated in Figure?1. It is possible, as well, to ignore the 2-D setup, and simply treat the results of a PangoLayout as a list of lines.

Figure?1.?Adjustable parameters for a PangoLayout

Adjustable parameters for a PangoLayout
Basicly, in gtk program, we can call gtk_widget_get_pango_context() to get a PangoContext pointer associated with this GtkWidget. With this context, we could get/set the font description, get/set language, list font families, get font metrics, even break a string of Unicode text. Must call pango_layout_context_changed() after changing the context attributes.
For PangoLayout, we could create a pango layout from one pango context, or use gtk_widget_create_pango_layout, ro deep-copy from another layout. From gtklabel/entry ... widgets, they provide the gtk_xxx_get_layout method to retrive the layout assoicated with the widget. Must call pango_layout_context_changed() after changing the layout attributes.
With PangoLayout, we can set the attributes, get/set text, get/set width, set (no get) font description, get/set wrap, get pixel/pango_unit size (and extention size).
#include <gtk/gtk.h>

gint main (gint argc, gchar *argv[])
   GtkWidget *window;
   GtkWidget *label;
   PangoFontDescription *font;

   gtk_init (&argc, &argv);

   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

   g_signal_connect (window, "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
   g_signal_connect (window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

   label = gtk_label_new ("Hello World!");
   font = pango_font_description_from_string ("monospace 30");
   gtk_widget_modify_font (label, font);

   gtk_container_add (GTK_CONTAINER(window), label);

   gtk_widget_show_all (window);

   gtk_main ();

   return 0;


改变控件字体大小: #include /* 功能: 设置控件字体大小 * widget: 需要改变字体的控件 * size: 字体大小 * is_butto...
  • tennysonsky
  • tennysonsky
  • 2015年01月26日 17:31
  • 2037


一、简介         Gtk+2.0控件的外观主要包括控件的背景颜色、控件的前景颜色、控件的字体等因素。控件的状态包括正常状态(GTK_STATE_NORMAL)、控件获得焦点时的状态(GTK_...
  • taiyang1987912
  • taiyang1987912
  • 2015年09月21日 16:24
  • 2146


字体大小用pango PangoFontDescription *font_desc = pango_font_description_from_string ("Serif 15");或 Pan...
  • maojudong
  • maojudong
  • 2008年03月12日 15:23
  • 2988

GTK里的label控件 颜色 大小 等  用过之后,你将会发现GTK里的label控件比windows系统的label功...
  • bitscro
  • bitscro
  • 2009年02月10日 16:37
  • 7197


   使用PangoFontDescription更改指定控件的样式   GtkWidget *entry = NULL;    entry = gtk_entry_new ();    PangoF...
  • c_spark
  • c_spark
  • 2009年08月14日 18:02
  • 2057


例子 代码:#!/usr/bin/env python3 # Created by xiaosanyu at 16/7/6 # section 141 TITLE = "Gradient" DESC...
  • a87b01c14
  • a87b01c14
  • 2016年08月03日 08:32
  • 1079


   使用PangoFontDescription更改指定控件的样式   GtkWidget *entry = NULL;    entry = gtk_entry_new ();    PangoF...
  • wanggang05194
  • wanggang05194
  • 2009年09月24日 09:04
  • 269


int res_title[81]; int res_content[501]; void search(char* key,char *title,char* content) { int i=0...
  • u011496301
  • u011496301
  • 2014年09月07日 02:08
  • 264

memo:Cairo 绘图

Cairo:  是一款绘图工具。前面在安装munin的时候发现需要这个东东。 概述: Cairo is a 2D graphics libra...
  • hantiannan
  • hantiannan
  • 2011年11月09日 15:46
  • 2275


caogaoxiang.c: #include #include GtkWidget *window_receive; //char * name = ""; /* 用...
  • u011496301
  • u011496301
  • 2014年09月07日 21:40
  • 317
您举报文章:Pango programming guide