Pango: Difference between revisions

From OLPC
Jump to navigation Jump to search
No edit summary
No edit summary
Line 2: Line 2:


=== How do I create a simple canvas that can render fonts using Pango? ===
=== How do I create a simple canvas that can render fonts using Pango? ===
Pango is built upon several other technologies, most notably gtk and Cairo. So to get pango working, you have to do a little coordinating between all of these players. The code below shows how I first create an extension of a gtk.DrawingArea class that will render Pango text. Then, I add this drawing area to a specific part of my UI (the first page in my main activity notebook widget).
Pango is built upon several other technologies, most notably gtk and Cairo. So to get pango working, you have to do a little coordinating between all of these players.

The diagram below explains the general relationship. Sugar and GTK arrange and control basic UI widgets (labels, notebooks, drawing areas, scroll bars, pull down menus, etc.). On top of these widgets, you can create Cairo and Pango contexts that coordinate the rendering of graphics and text respectively. Pango is built on top of Cairo, which is a general purpose graphics rendering library. Pango is specialized for text.

Given this broad architecture, text rendered through Pango requires a UI widget where the text will show up and then a Cairo context that will be used to help do the graphics rendering needed by Pango. The code below shows how I first create an extension of a gtk.DrawingArea class that will be the UI widget where our Pango text will display. This widget, which I call TextWidget, can then be placed somewhere in the larger gtk/sugar UI (we put it on the first page of the main notebook widget for our activity).

In this structure, most of the meaty code is in the expose_cb() method, which is called when an "expose_event" signal is sent out.


<pre>
<pre>
Line 40: Line 46:
self.layout.set_wrap(pango.WRAP_WORD)
self.layout.set_wrap(pango.WRAP_WORD)
self.layout.set_width(500*pango.SCALE)
self.layout.set_width(500*pango.SCALE)
self.layout.set_font_description(pango.FontDescription('Serif 14'))
self.layout.set_font_description(pango.FontDescription('Serif 14'))

#This is a basic command to set the text that will be rendered using Pango.
self.layout.set_markup('<span foreground=\"blue\">This is some sample markup</span> <sup>text</sup> that <u>is displayed with pango</u>')
self.layout.set_markup('<span foreground=\"blue\">This is some sample markup</span> <sup>text</sup> that <u>is displayed with pango</u>')


Line 48: Line 56:
</pre>
</pre>



Below is the code we put in our initial class that will create the larger UI for the activity. Note how we create a sugar.graphics.notebook.Notebook object as the main container for the "stuff" in our activity. Then we populate this notebook with more UI widget. The one widget of interest for us is the TextWidget object that is placed on the first page of the activity.
<pre>
<pre>
from TextWidget import TextWidget
#-----------------------------------FILE: TextWidget.py ----------------------------------------
from sugar.graphics.notebook import Notebook
#### Method: _createCanvas, creates a top level canvas object for this activity
...
def _createCanvas(self):
top_container = Notebook()
top_container = Notebook()
Line 68: Line 78:
top_container.add_page('Third Page', third_page)
top_container.add_page('Third Page', third_page)
return top_container
return top_container


</pre>
</pre>



Revision as of 21:26, 16 July 2008

Pango is "the core text and font handling library used in GNOME applications. It has extensive support for the different writing systems used throughout the world."<ref>Pango Reference Manual</ref>. The end of this section points to some standard documentation of Pango that should help you walk through most of what you want to do. We will simply discuss a few representative examples to help you get started in using Pango to display text in your activity.

How do I create a simple canvas that can render fonts using Pango?

Pango is built upon several other technologies, most notably gtk and Cairo. So to get pango working, you have to do a little coordinating between all of these players.

The diagram below explains the general relationship. Sugar and GTK arrange and control basic UI widgets (labels, notebooks, drawing areas, scroll bars, pull down menus, etc.). On top of these widgets, you can create Cairo and Pango contexts that coordinate the rendering of graphics and text respectively. Pango is built on top of Cairo, which is a general purpose graphics rendering library. Pango is specialized for text.

Given this broad architecture, text rendered through Pango requires a UI widget where the text will show up and then a Cairo context that will be used to help do the graphics rendering needed by Pango. The code below shows how I first create an extension of a gtk.DrawingArea class that will be the UI widget where our Pango text will display. This widget, which I call TextWidget, can then be placed somewhere in the larger gtk/sugar UI (we put it on the first page of the main notebook widget for our activity).

In this structure, most of the meaty code is in the expose_cb() method, which is called when an "expose_event" signal is sent out.

#-----------------------------------FILE: TextWidget.py ----------------------------------------
import gtk

from gtk import gdk
import cairo
import pango

class TextWidget(gtk.DrawingArea):

	def __init__(self):
		
		gtk.DrawingArea.__init__(self)

		self.layout = None

		self.connect("expose_event", self.expose_cb)
		self.set_size_request(450, -1)


	#The expose method is automatically called when the widget
	#needs to be redrawn
	def expose_cb(self, widget, event):
		
		#create a CAIRO context (to use with pango)
		self.context = widget.window.cairo_create()

		#clip anything outside the drawing rectangle
		self.context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
		self.context.clip()

		#create a pango layout and set its text
		self.pango_context = self.create_pango_context()
		self.layout = pango.Layout(self.pango_context)
		self.layout.set_wrap(pango.WRAP_WORD)
		self.layout.set_width(500*pango.SCALE)
		self.layout.set_font_description(pango.FontDescription('Serif 14'))	

                #This is a basic command to set the text that will be rendered using Pango.	
		self.layout.set_markup('<span foreground=\"blue\">This is some sample markup</span> <sup>text</sup> that <u>is displayed with pango</u>')

		self.context.show_layout(self.layout)



Below is the code we put in our initial class that will create the larger UI for the activity. Note how we create a sugar.graphics.notebook.Notebook object as the main container for the "stuff" in our activity. Then we populate this notebook with more UI widget. The one widget of interest for us is the TextWidget object that is placed on the first page of the activity.

from TextWidget import TextWidget
from sugar.graphics.notebook import Notebook
...
        top_container = Notebook()
        
        #Create pages for the notebook
        first_page = gtk.VBox()
        #Create a TextWidget object that can display pango markup text and add it to the first page
        tw = TextWidget()
        first_page.pack_start(tw)

        second_page = gtk.VBox()
        third_page = gtk.Frame()

        #Add the pages to the notebook. 
        top_container.add_page('First Page', first_page)
        top_container.add_page('Second Page', second_page)
        top_container.add_page('Third Page', third_page)
        return top_container

Notes

<references />