diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-0 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-10 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-2 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-4 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-6 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-8 | 25 | ||||
-rw-r--r-- | TODO | 44 | ||||
-rw-r--r-- | docs/Makefile.am | 3 | ||||
-rw-r--r-- | docs/TEXT/coding-style | 115 | ||||
-rw-r--r-- | docs/layout.eps | 231 | ||||
-rw-r--r-- | docs/layout.fig | 75 | ||||
-rw-r--r-- | docs/layout.gif | bin | 0 -> 5572 bytes | |||
-rw-r--r-- | docs/pango-sections.txt | 33 | ||||
-rw-r--r-- | docs/tmpl/glyphs.sgml | 40 | ||||
-rw-r--r-- | docs/tmpl/layout.sgml | 193 | ||||
-rw-r--r-- | docs/tmpl/main.sgml | 28 | ||||
-rw-r--r-- | docs/tmpl/pango-unused.sgml | 85 | ||||
-rw-r--r-- | docs/tmpl/x-rendering.sgml | 38 | ||||
-rw-r--r-- | examples/viewer.c | 178 | ||||
-rw-r--r-- | modules/arabic/.cvsignore | 6 | ||||
-rw-r--r-- | modules/arabic/arabic-x.c | 92 | ||||
-rw-r--r-- | modules/arabic/arabic.c | 92 | ||||
-rw-r--r-- | modules/arabic/arconv.c | 159 | ||||
-rw-r--r-- | modules/arabic/arconv.h | 3 | ||||
-rw-r--r-- | pango/fonts.c | 2 | ||||
-rw-r--r-- | pango/modules.c | 2 | ||||
-rw-r--r-- | pango/pango-layout.c | 372 | ||||
-rw-r--r-- | pango/pango-layout.h | 70 | ||||
-rw-r--r-- | pango/pangox.c | 98 | ||||
-rw-r--r-- | pango/pangox.h | 8 |
31 files changed, 1686 insertions, 456 deletions
@@ -1,3 +1,28 @@ +Thu Mar 9 19:55:21 2000 Owen Taylor <otaylor@redhat.com> + + * Release pango-0.8 + + * docs/TEXT/coding-style: Added some notes about coding style + within Pango. + + * modules/*.[ch]: New version from Karl Koehler adding support + for vowels marks, better ligatures. + + * docs/tmpl/*: Doc updates + + * libpango/pango-layout.[ch] libpango/pangox/.[ch]: Add functions + for handling paragraphs as 2-D objects, not simple lists of lines, + to make things easier for people using pango-layout. + + * examples/viewer.c: Simplify using the now 2-D layout-capabable + PangoLayout. + + * libpango/fonts.c (pango_font_{get_coverage,find_shaper}): Allow + NULL language tag. + + * libpango/modules.c (_pango_find_map): Fix for allowing + NULL language tag. + Wed Mar 8 13:34:57 2000 Owen Taylor <otaylor@redhat.com> * libpango/pango-layout.[ch]: First draft of highlevel diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0 index adeda523..f44da35a 100644 --- a/ChangeLog.pre-1-0 +++ b/ChangeLog.pre-1-0 @@ -1,3 +1,28 @@ +Thu Mar 9 19:55:21 2000 Owen Taylor <otaylor@redhat.com> + + * Release pango-0.8 + + * docs/TEXT/coding-style: Added some notes about coding style + within Pango. + + * modules/*.[ch]: New version from Karl Koehler adding support + for vowels marks, better ligatures. + + * docs/tmpl/*: Doc updates + + * libpango/pango-layout.[ch] libpango/pangox/.[ch]: Add functions + for handling paragraphs as 2-D objects, not simple lists of lines, + to make things easier for people using pango-layout. + + * examples/viewer.c: Simplify using the now 2-D layout-capabable + PangoLayout. + + * libpango/fonts.c (pango_font_{get_coverage,find_shaper}): Allow + NULL language tag. + + * libpango/modules.c (_pango_find_map): Fix for allowing + NULL language tag. + Wed Mar 8 13:34:57 2000 Owen Taylor <otaylor@redhat.com> * libpango/pango-layout.[ch]: First draft of highlevel diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index adeda523..f44da35a 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,28 @@ +Thu Mar 9 19:55:21 2000 Owen Taylor <otaylor@redhat.com> + + * Release pango-0.8 + + * docs/TEXT/coding-style: Added some notes about coding style + within Pango. + + * modules/*.[ch]: New version from Karl Koehler adding support + for vowels marks, better ligatures. + + * docs/tmpl/*: Doc updates + + * libpango/pango-layout.[ch] libpango/pangox/.[ch]: Add functions + for handling paragraphs as 2-D objects, not simple lists of lines, + to make things easier for people using pango-layout. + + * examples/viewer.c: Simplify using the now 2-D layout-capabable + PangoLayout. + + * libpango/fonts.c (pango_font_{get_coverage,find_shaper}): Allow + NULL language tag. + + * libpango/modules.c (_pango_find_map): Fix for allowing + NULL language tag. + Wed Mar 8 13:34:57 2000 Owen Taylor <otaylor@redhat.com> * libpango/pango-layout.[ch]: First draft of highlevel diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2 index adeda523..f44da35a 100644 --- a/ChangeLog.pre-1-2 +++ b/ChangeLog.pre-1-2 @@ -1,3 +1,28 @@ +Thu Mar 9 19:55:21 2000 Owen Taylor <otaylor@redhat.com> + + * Release pango-0.8 + + * docs/TEXT/coding-style: Added some notes about coding style + within Pango. + + * modules/*.[ch]: New version from Karl Koehler adding support + for vowels marks, better ligatures. + + * docs/tmpl/*: Doc updates + + * libpango/pango-layout.[ch] libpango/pangox/.[ch]: Add functions + for handling paragraphs as 2-D objects, not simple lists of lines, + to make things easier for people using pango-layout. + + * examples/viewer.c: Simplify using the now 2-D layout-capabable + PangoLayout. + + * libpango/fonts.c (pango_font_{get_coverage,find_shaper}): Allow + NULL language tag. + + * libpango/modules.c (_pango_find_map): Fix for allowing + NULL language tag. + Wed Mar 8 13:34:57 2000 Owen Taylor <otaylor@redhat.com> * libpango/pango-layout.[ch]: First draft of highlevel diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index adeda523..f44da35a 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,3 +1,28 @@ +Thu Mar 9 19:55:21 2000 Owen Taylor <otaylor@redhat.com> + + * Release pango-0.8 + + * docs/TEXT/coding-style: Added some notes about coding style + within Pango. + + * modules/*.[ch]: New version from Karl Koehler adding support + for vowels marks, better ligatures. + + * docs/tmpl/*: Doc updates + + * libpango/pango-layout.[ch] libpango/pangox/.[ch]: Add functions + for handling paragraphs as 2-D objects, not simple lists of lines, + to make things easier for people using pango-layout. + + * examples/viewer.c: Simplify using the now 2-D layout-capabable + PangoLayout. + + * libpango/fonts.c (pango_font_{get_coverage,find_shaper}): Allow + NULL language tag. + + * libpango/modules.c (_pango_find_map): Fix for allowing + NULL language tag. + Wed Mar 8 13:34:57 2000 Owen Taylor <otaylor@redhat.com> * libpango/pango-layout.[ch]: First draft of highlevel diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index adeda523..f44da35a 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,28 @@ +Thu Mar 9 19:55:21 2000 Owen Taylor <otaylor@redhat.com> + + * Release pango-0.8 + + * docs/TEXT/coding-style: Added some notes about coding style + within Pango. + + * modules/*.[ch]: New version from Karl Koehler adding support + for vowels marks, better ligatures. + + * docs/tmpl/*: Doc updates + + * libpango/pango-layout.[ch] libpango/pangox/.[ch]: Add functions + for handling paragraphs as 2-D objects, not simple lists of lines, + to make things easier for people using pango-layout. + + * examples/viewer.c: Simplify using the now 2-D layout-capabable + PangoLayout. + + * libpango/fonts.c (pango_font_{get_coverage,find_shaper}): Allow + NULL language tag. + + * libpango/modules.c (_pango_find_map): Fix for allowing + NULL language tag. + Wed Mar 8 13:34:57 2000 Owen Taylor <otaylor@redhat.com> * libpango/pango-layout.[ch]: First draft of highlevel diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index adeda523..f44da35a 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,28 @@ +Thu Mar 9 19:55:21 2000 Owen Taylor <otaylor@redhat.com> + + * Release pango-0.8 + + * docs/TEXT/coding-style: Added some notes about coding style + within Pango. + + * modules/*.[ch]: New version from Karl Koehler adding support + for vowels marks, better ligatures. + + * docs/tmpl/*: Doc updates + + * libpango/pango-layout.[ch] libpango/pangox/.[ch]: Add functions + for handling paragraphs as 2-D objects, not simple lists of lines, + to make things easier for people using pango-layout. + + * examples/viewer.c: Simplify using the now 2-D layout-capabable + PangoLayout. + + * libpango/fonts.c (pango_font_{get_coverage,find_shaper}): Allow + NULL language tag. + + * libpango/modules.c (_pango_find_map): Fix for allowing + NULL language tag. + Wed Mar 8 13:34:57 2000 Owen Taylor <otaylor@redhat.com> * libpango/pango-layout.[ch]: First draft of highlevel @@ -5,25 +5,26 @@ Layout Driver ============= The PangoLayout object is a highlevel driver that takes an attributed -string and produces lines of glyphs. As well as just implementing -this, there are various improvements that need to be made to +string and produces lines of glyphs. * Figure out better ways of doing line breaks. (This may involve implementing the TeX/Raph x0-x1 stuff for line breaks.) -X rendering -=========== +* Add spacing parameter as illustrated; this should be a quick + (10 minute) addition. -* The point-size/pixel size handling is not done right. Right - now we are just assuming pixel == point, because trying to - use the point-size fields of the X fonts didn't work on - systems with both 100 and 75 dpi fonts installed. +* Although PangoLayout isn't intended to handle large amounts + of text, it should be able to handle embedded "\n" and simple + multiple paragraphs. This could be done entirely within + pango_layout_check_lines() - We should query the X server for its actual reported value - and use that to translate point size to pixel size. +* Attribute handling needs to be added (fg/bg/underline, etc.) + Each PangoItem should have a list of associated non-font + attributes ... though this would require a bit more thought + as to memory-management of PangoItem, which is currently add-hoc. - (This doesn't really handle the case of optically scaled - bitmaps properly, but I think that is an ignorable problem.) +X rendering +=========== * Right now we assume a single resolution for all fonts on a display; but in theory, the resolution could be per-screen. To solve @@ -34,8 +35,11 @@ X rendering Other rendering engines ====================== -Somebody should start working on a libart font-system / renderer -soon, to make sure that the interfaces are suitable. +* Somebody should start working on a libart font-system / renderer + soon, to make sure that the interfaces are suitable. + +* FreeType-2.0 support could be very interesting, with the OpenType + that it has. Engines ======= @@ -46,8 +50,10 @@ Engines Language Modules ================ - * It would be nice to have X based renderers for a few more scripts; - Arabic in particular is one such script. + * It would be nice to have X based shapers for a few more scripts; + Hindi is one obvious need. (Actually, there may be a need for + a generic framework for Indic shapers to be developed. A + libpango-indic...) * Once we have a libart renderer, porting Raph's devanagari shaper to Pango and C (from Perl) would be a cool demo and test case. @@ -103,4 +109,8 @@ General * Finish coverting over from utils.c to Tom Tromey's libunicode. Add the remaining useful functions from utils.c into libunicode. -* s/num_chars/n_chars/ etc. (Always use n_ as enumeration prefix)
\ No newline at end of file +* s/num_chars/n_chars/ etc. (Always use n_ as enumeration prefix) + +* Underline attribute should be an enumeration (none/single/double/squiggle/low, + where low is below the ink rect - a style appropriate for underline + accelerators.)
\ No newline at end of file diff --git a/docs/Makefile.am b/docs/Makefile.am index 255916d5..8144ba54 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -23,6 +23,7 @@ sgml: html: if ! test -d html ; then mkdir html ; fi -cd html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) + cp layout.gif html clean-local: rm -f *~ *.bak *.hierarchy *.signals *.args *-unused.txt @@ -34,7 +35,7 @@ maintainer-clean-local: clean endif -EXTRA_DIST=pango-sections.txt pango-docs.sgml +EXTRA_DIST=pango-sections.txt pango-docs.sgml layout.fig layout.eps layout.fig dist-hook: mkdir $(distdir)/tmpl diff --git a/docs/TEXT/coding-style b/docs/TEXT/coding-style new file mode 100644 index 00000000..04526c9c --- /dev/null +++ b/docs/TEXT/coding-style @@ -0,0 +1,115 @@ +Formatting +========== + +All parts of Pango other than modules should use the following formatting +style; for modules, it is up to the discretion of the module +author / maintainer, though they are encouraged to follow the following. + +The Pango formatting style is basically the GNU style of formatting +(see http://www.gnu.org/prep/standards.html), with a few additions. +In brief overview: + + - Two character indents are used; braces go on a separate line, and + get a separate indentation level, so the total indent for an + enclosed block is 4 characters. + + if (x < foo (y, z)) + haha = bar[4] + 5; + else + { + while (z) + { + haha += foo (z, z); + z--; + } + return abc (haha); + } + + - Spaces should be present between function name and argument block, + and after commas. + + foo (z, z) + + - In pointer types, the '*' is grouped with the variable name, + not with the base type. + + int *a; + + NOT: 'int* a'. + + In cases where there is no variable name, for instance, return + values, there should be a single space between the base type + and the '*'. + + - function and variable names are lower_case_with_underscores + type names are StudlyCaps, macro names are UPPER_CASE_WITH_UNDERSCORES + + +Documentation comments +====================== + +All public API functions should have inline documentation headers +in the gtk-doc / gnome-doc style. For instance: + +/** + * pango_layout_get_line: + * @layout: a #PangoLayout + * @line: the index of a line, which must be between 0 and + * pango_layout_get_line_count(layout) - 1, inclusive. + * + * Retrieves a particular line from a #PangoLayout + * + * Return value: the requested #PangoLayoutLine, or %NULL if the + * index is out of range. This layout line can + * be ref'ed and retained, but will become invalid + * if changes are made to the #PangoLayout. + **/ +PangoLayoutLine * +pango_layout_get_line (PangoLayout *layout, + int line) +[...] + +An Emacs lisp file is distributed with gnome-libs which automates +inserting these comments + +Choosing Function Names +======================= + +- Don't abbreviate in unexpected ways: + + pango_layout_get_line_count () + + Not: + + pango_layout_ln_cnt () + +- function that retrieve a value in a side-effect free fashion, should + include "get" in the name. + + int pango_layout_get_line_count (PangoLayout *layout) + + not + + pango_layout_line_count () + + +- functions that set a single parameter in a side-effect free fashion + should include "set" in the name, for instance: + + void pango_layout_set_width (PangoLayout *layout, + int width); + +Other comments +============== + +- Avoid unsigned values for all but flags fields. This is because + the way C handles unsigned values generates bugs like crazy: + + If width is unsigned and 10, then: + + int new_width = MAX (width - 15, 1); + + produces 4294967291, not 1. + + + diff --git a/docs/layout.eps b/docs/layout.eps new file mode 100644 index 00000000..42c897ab --- /dev/null +++ b/docs/layout.eps @@ -0,0 +1,231 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: layout.eps +%%Creator: fig2dev Version 3.2 Patchlevel 1 +%%CreationDate: Thu Mar 9 16:51:04 2000 +%%For: otaylor@fresnel.labs.redhat.com (Owen Taylor,,547-0012 x249) +%%Orientation: Portrait +%%BoundingBox: 0 0 629 233 +%%Pages: 0 +%%BeginSetup +%%EndSetup +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def +/col32 {0.443 0.459 0.443 srgb} bind def + +end +save +-5.0 253.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def +%%EndProlog + +$F2psBegin +10 setmiterlimit +n -1000 5215 m -1000 -1000 l 11561 -1000 l 11561 5215 l cp clip + 0.06000 0.06000 sc +% Polyline +15.000 slw +gs clippath +10200 3405 m 10350 3450 l 10200 3495 l 10380 3495 l 10380 3405 l cp +6300 3495 m 6150 3450 l 6300 3405 l 6120 3405 l 6120 3495 l cp +clip +n 6150 3450 m 10350 3450 l gs col-1 s gr gr + +% arrowhead +7.500 slw +n 6300 3495 m 6150 3450 l 6300 3405 l 6300 3450 l 6300 3495 l cp gs 0.00 setgray ef gr col-1 s +% arrowhead +n 10200 3405 m 10350 3450 l 10200 3495 l 10200 3450 l 10200 3405 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +n 1200 675 m 1200 3600 l gs col-1 s gr +% Polyline +15.000 slw +gs clippath +5250 3405 m 5400 3450 l 5250 3495 l 5430 3495 l 5430 3405 l cp +1350 3495 m 1200 3450 l 1350 3405 l 1170 3405 l 1170 3495 l cp +clip +n 1200 3450 m 5400 3450 l gs col-1 s gr gr + +% arrowhead +7.500 slw +n 1350 3495 m 1200 3450 l 1350 3405 l 1350 3450 l 1350 3495 l cp gs 0.00 setgray ef gr col-1 s +% arrowhead +n 5250 3405 m 5400 3450 l 5250 3495 l 5250 3450 l 5250 3405 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +n 1050 2175 m 1200 2175 l gs col-1 s gr +% Polyline +15.000 slw +n 1125 2025 m 1125 2175 l gs col-1 s gr +% Polyline +7.500 slw +n 6150 975 m 6150 3600 l gs col-1 s gr +% Polyline +n 5400 975 m 5400 3600 l gs col-1 s gr +% Polyline +n 1800 975 m 1800 675 l gs col-1 s gr +% Polyline +15.000 slw +gs clippath +1650 780 m 1800 825 l 1650 870 l 1830 870 l 1830 780 l cp +1350 870 m 1200 825 l 1350 780 l 1170 780 l 1170 870 l cp +clip +n 1200 825 m 1800 825 l gs col-1 s gr gr + +% arrowhead +7.500 slw +n 1350 870 m 1200 825 l 1350 780 l 1350 825 l 1350 870 l cp gs 0.00 setgray ef gr col-1 s +% arrowhead +n 1650 780 m 1800 825 l 1650 870 l 1650 825 l 1650 780 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +n 9750 975 m 9750 675 l gs col-1 s gr +% Polyline +15.000 slw +gs clippath +10200 780 m 10350 825 l 10200 870 l 10380 870 l 10380 780 l cp +9900 870 m 9750 825 l 9900 780 l 9720 780 l 9720 870 l cp +clip +n 9750 825 m 10350 825 l gs col-1 s gr gr + +% arrowhead +7.500 slw +n 9900 870 m 9750 825 l 9900 780 l 9900 825 l 9900 870 l cp gs 0.00 setgray ef gr col-1 s +% arrowhead +n 10200 780 m 10350 825 l 10200 870 l 10200 825 l 10200 780 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +n 10350 675 m 10350 3600 l gs col-1 s gr +% Polyline +15.000 slw +n 4950 1425 m 1800 1425 l 1800 975 l 4950 975 l cp gs col32 s gr +% Polyline +n 4575 2025 m 1200 2025 l 1200 1575 l 4575 1575 l cp gs col32 s gr +% Polyline +n 5250 2625 m 1200 2625 l 1200 2175 l 5250 2175 l cp gs col32 s gr +% Polyline +n 2400 3225 m 1200 3225 l 1200 2775 l 2400 2775 l cp gs col32 s gr +% Polyline +n 9750 1425 m 6600 1425 l 6600 975 l 9750 975 l cp gs col32 s gr +% Polyline +n 10350 2025 m 6975 2025 l 6975 1575 l 10350 1575 l cp gs col32 s gr +% Polyline +n 10350 2625 m 6300 2625 l 6300 2175 l 10350 2175 l cp gs col32 s gr +% Polyline +n 10350 3225 m 9150 3225 l 9150 2775 l 10350 2775 l cp gs col32 s gr +% Polyline +7.500 slw +n 1200 2025 m 1050 2025 l gs col-1 s gr +/Times-Roman ff 360.00 scf sf +1200 2475 m +gs 1 -1 sc (demonstrate PangoLayout's) col0 sh gr +/Times-Roman ff 360.00 scf sf +1200 3075 m +gs 1 -1 sc (features.) col0 sh gr +/Times-Roman ff 360.00 scf sf +1200 1875 m +gs 1 -1 sc (should wrap suitably to) col0 sh gr +/Helvetica ff 240.00 scf sf +525 2175 m +gs 1 -1 sc (spacing) dup sw pop 2 div neg 0 rm col-1 sh gr +/Times-Roman ff 360.00 scf sf +1800 1275 m +gs 1 -1 sc (Here is some text that) col0 sh gr +/Times-Roman ff 360.00 scf sf +9150 3075 m +gs 1 -1 sc (features.) col0 sh gr +/Times-Roman ff 360.00 scf sf +6600 1275 m +gs 1 -1 sc (Here is some text that) col0 sh gr +/Helvetica ff 240.00 scf sf +1875 3825 m +gs 1 -1 sc (width) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica ff 240.00 scf sf +6825 3825 m +gs 1 -1 sc (width) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica ff 240.00 scf sf +10050 525 m +gs 1 -1 sc (indent) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica ff 240.00 scf sf +1575 525 m +gs 1 -1 sc (indent) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica ff 300.00 scf sf +9225 4125 m +gs 1 -1 sc (Right Aligned) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica ff 300.00 scf sf +4350 4125 m +gs 1 -1 sc (Left Aligned) dup sw pop 2 div neg 0 rm col-1 sh gr +/Times-Roman ff 360.00 scf sf +6975 1875 m +gs 1 -1 sc (should wrap suitably to) col0 sh gr +/Times-Roman ff 360.00 scf sf +6300 2475 m +gs 1 -1 sc (demonstrate PangoLayout's) col0 sh gr +$F2psEnd +rs diff --git a/docs/layout.fig b/docs/layout.fig new file mode 100644 index 00000000..7e43560b --- /dev/null +++ b/docs/layout.fig @@ -0,0 +1,75 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +0 32 #717571 +2 1 0 2 -1 7 100 0 -1 0.000 0 0 -1 1 1 2 + 1 1 1.00 90.00 150.00 + 1 1 1.00 90.00 150.00 + 6150 3450 10350 3450 +2 1 0 1 -1 7 100 0 -1 0.000 0 0 -1 0 0 2 + 1200 675 1200 3600 +2 1 0 2 -1 7 100 0 -1 0.000 0 0 -1 1 1 2 + 1 1 1.00 90.00 150.00 + 1 1 1.00 90.00 150.00 + 1200 3450 5400 3450 +2 1 0 1 -1 7 100 0 -1 0.000 0 0 -1 0 0 2 + 1050 2175 1200 2175 +2 1 0 2 -1 7 100 0 -1 0.000 0 0 -1 0 0 2 + 1125 2025 1125 2175 +2 1 0 1 -1 7 100 0 -1 0.000 0 0 -1 0 0 2 + 6150 975 6150 3600 +2 1 0 1 -1 7 100 0 -1 0.000 0 0 -1 0 0 2 + 5400 975 5400 3600 +2 1 0 1 -1 7 100 0 -1 0.000 0 0 -1 0 0 2 + 1800 975 1800 675 +2 1 0 2 -1 7 100 0 -1 0.000 0 0 -1 1 1 2 + 1 1 1.00 90.00 150.00 + 1 1 1.00 90.00 150.00 + 1200 825 1800 825 +2 1 0 1 -1 7 100 0 -1 0.000 0 0 -1 0 0 2 + 9750 975 9750 675 +2 1 0 2 -1 7 100 0 -1 0.000 0 0 -1 1 1 2 + 1 1 1.00 90.00 150.00 + 1 1 1.00 90.00 150.00 + 9750 825 10350 825 +2 1 0 1 -1 7 100 0 -1 0.000 0 0 -1 0 0 2 + 10350 675 10350 3600 +2 2 0 2 32 7 100 0 -1 0.000 0 0 -1 0 0 5 + 4950 1425 1800 1425 1800 975 4950 975 4950 1425 +2 2 0 2 32 7 100 0 -1 0.000 0 0 -1 0 0 5 + 4575 2025 1200 2025 1200 1575 4575 1575 4575 2025 +2 2 0 2 32 7 100 0 -1 0.000 0 0 -1 0 0 5 + 5250 2625 1200 2625 1200 2175 5250 2175 5250 2625 +2 2 0 2 32 7 100 0 -1 0.000 0 0 -1 0 0 5 + 2400 3225 1200 3225 1200 2775 2400 2775 2400 3225 +2 2 0 2 32 7 100 0 -1 0.000 0 0 -1 0 0 5 + 9750 1425 6600 1425 6600 975 9750 975 9750 1425 +2 2 0 2 32 7 100 0 -1 0.000 0 0 -1 0 0 5 + 10350 2025 6975 2025 6975 1575 10350 1575 10350 2025 +2 2 0 2 32 7 100 0 -1 0.000 0 0 -1 0 0 5 + 10350 2625 6300 2625 6300 2175 10350 2175 10350 2625 +2 2 0 2 32 7 100 0 -1 0.000 0 0 -1 0 0 5 + 10350 3225 9150 3225 9150 2775 10350 2775 10350 3225 +2 1 0 1 -1 7 100 0 -1 0.000 0 0 -1 0 0 2 + 1200 2025 1050 2025 +4 0 0 100 0 0 24 0.0000 4 330 4155 1200 2475 demonstrate PangoLayout's\001 +4 0 0 100 0 0 24 0.0000 4 255 1260 1200 3075 features.\001 +4 0 0 100 0 0 24 0.0000 4 330 3405 1200 1875 should wrap suitably to\001 +4 1 -1 100 0 16 16 0.0000 4 240 855 525 2175 spacing\001 +4 0 0 100 0 0 24 0.0000 4 255 3270 1800 1275 Here is some text that\001 +4 0 0 100 0 0 24 0.0000 4 255 1260 9150 3075 features.\001 +4 0 0 100 0 0 24 0.0000 4 255 3270 6600 1275 Here is some text that\001 +4 1 -1 100 0 16 16 0.0000 4 180 540 1875 3825 width\001 +4 1 -1 100 0 16 16 0.0000 4 180 540 6825 3825 width\001 +4 1 -1 100 0 16 16 0.0000 4 180 645 10050 525 indent\001 +4 1 -1 100 0 16 16 0.0000 4 180 645 1575 525 indent\001 +4 1 -1 100 0 16 20 0.0000 4 300 1770 9225 4125 Right Aligned\001 +4 1 -1 100 0 16 20 0.0000 4 300 1590 4350 4125 Left Aligned\001 +4 0 0 100 0 0 24 0.0000 4 330 3405 6975 1875 should wrap suitably to\001 +4 0 0 100 0 0 24 0.0000 4 330 4155 6300 2475 demonstrate PangoLayout's\001 diff --git a/docs/layout.gif b/docs/layout.gif Binary files differnew file mode 100644 index 00000000..96bde1f2 --- /dev/null +++ b/docs/layout.gif diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt index 57809132..9c606fa5 100644 --- a/docs/pango-sections.txt +++ b/docs/pango-sections.txt @@ -29,9 +29,6 @@ PangoLogAttr <SUBSECTION> pango_shape pango_justify -<SUBSECTION> -pango_cp_to_x -pango_x_to_cp </SECTION> <SECTION> @@ -52,6 +49,9 @@ pango_glyph_string_new pango_glyph_string_set_size pango_glyph_string_free pango_glyph_string_extents +pango_glyph_string_index_to_x +pango_glyph_string_x_to_index +pango_glyph_string_get_logical_widths </SECTION> <SECTION> @@ -153,8 +153,6 @@ pango_attr_iterator_destroy <TITLE>Layout Objects</TITLE> <FILE>layout</FILE> PangoLayout -PangoLayoutLine -PangoLayoutRun pango_layout_new pango_layout_ref pango_layout_unref @@ -162,17 +160,32 @@ pango_layout_unref pango_layout_set_text pango_layout_set_attributes pango_layout_set_width -pango_layout_set_first_line_width +pango_layout_get_width +pango_layout_set_indent +pango_layout_get_indent pango_layout_set_justify +pango_layout_get_justify +pango_layout_set_alignment +pango_layout_get_alignment +PangoAlignment + +pango_layout_xy_to_index +pango_layout_index_to_pos -pango_layout_cp_to_line_x +pango_layout_get_extents pango_layout_get_line_count pango_layout_get_line +pango_layout_get_lines + +<SUBSECTION> +PangoLayoutLine +PangoLayoutRun pango_layout_line_ref pango_layout_line_unref -pango_layout_line_x_to_cp pango_layout_line_get_extents +pango_layout_line_index_to_x +pango_layout_line_x_to_index </SECTION> <SECTION> @@ -197,8 +210,8 @@ script_engine_unload PANGO_RENDER_TYPE_X pango_x_get_context pango_x_render -pango_x_extents -pango_x_glyph_extents +pango_x_render_layout_line +pango_x_render_layout </SECTION> <SECTION> diff --git a/docs/tmpl/glyphs.sgml b/docs/tmpl/glyphs.sgml index ad3fad44..d98587a5 100644 --- a/docs/tmpl/glyphs.sgml +++ b/docs/tmpl/glyphs.sgml @@ -256,3 +256,43 @@ accessible fields @logical_rect: +<!-- ##### FUNCTION pango_glyph_string_index_to_x ##### --> +<para> + +</para> + +@glyphs: +@text: +@length: +@analysis: +@index: +@trailing: +@x_pos: + + +<!-- ##### FUNCTION pango_glyph_string_x_to_index ##### --> +<para> + +</para> + +@glyphs: +@text: +@length: +@analysis: +@x_pos: +@index: +@trailing: + + +<!-- ##### FUNCTION pango_glyph_string_get_logical_widths ##### --> +<para> + +</para> + +@glyphs: +@text: +@length: +@embedding_level: +@logical_widths: + + diff --git a/docs/tmpl/layout.sgml b/docs/tmpl/layout.sgml index aa44fd98..7593c90f 100644 --- a/docs/tmpl/layout.sgml +++ b/docs/tmpl/layout.sgml @@ -2,7 +2,7 @@ Layout Objects <!-- ##### SECTION Short_Description ##### --> -Layout driver objects for entire paragraphs. +Highlevel layout driver objects <!-- ##### SECTION Long_Description ##### --> <para> @@ -23,44 +23,36 @@ at once. <para> The #PangoLayout structure represents and entire paragraph of text. It is initialized with a #PangoContext, UTF-8 string -and set of attirbutes for that string. Once that is done, the -set of formatted lines can be extracted from the object. +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. </para> - -<!-- ##### STRUCT PangoLayoutLine ##### --> -<para> -The #PangoLayoutLine structure represents one of the lines resulting -from laying out a paragraph via #PangoLayout. #PangoLayoutLine -structures are obtained by calling pango_layout_get_line() and -are only valid until the text, attributes, or settings of the -parent #PangoLayout are modified. -</para> <para> -Routines for rendering PangoLayout objects are provided in -code specific to each rendering system. +There are also a number of parameters to adjust the formatting +of a #PangoLayout, which are illustrated in <xref linkend="parameters">. +It is possible, as well, to ignore the 2-D setup, and simply +treat the results of a #PangoLayout as a list of lines. </para> -@layout: the parent layout for this line. -@n_chars: the total number of characters in the line. -@length: the length of the line in bytes. -@runs: a list containing the runs of the line in visual order. +<figure id="parameters"> +<title>Adjustable parameters for a PangoLayout</title> +<graphic fileref="layout.gif" format="gif"></graphic> +</figure> -<!-- ##### STRUCT PangoLayoutRun ##### --> <para> -The #PangoLayoutRun structure represents a single run within -a #PangoLayoutLine. +The #PangoLayout structure is opaque, and has no user-visible +fields. </para> -@item: a #PangoItem structure that provides information - about the segment of text in this run. -@glyphs: the glyphs obtained by shaping the text for this item. - <!-- ##### FUNCTION pango_layout_new ##### --> <para> </para> +@context: @Returns: @@ -85,6 +77,7 @@ a #PangoLayoutLine. </para> +@layout: @text: @length: @@ -107,13 +100,31 @@ a #PangoLayoutLine. @width: -<!-- ##### FUNCTION pango_layout_set_first_line_width ##### --> +<!-- ##### FUNCTION pango_layout_get_width ##### --> <para> </para> @layout: -@width: +@Returns: + + +<!-- ##### FUNCTION pango_layout_set_indent ##### --> +<para> + +</para> + +@layout: +@indent: + + +<!-- ##### FUNCTION pango_layout_get_indent ##### --> +<para> + +</para> + +@layout: +@Returns: <!-- ##### FUNCTION pango_layout_set_justify ##### --> @@ -125,16 +136,76 @@ a #PangoLayoutLine. @justify: -<!-- ##### FUNCTION pango_layout_cp_to_line_x ##### --> +<!-- ##### FUNCTION pango_layout_get_justify ##### --> +<para> + +</para> + +@layout: +@Returns: + + +<!-- ##### FUNCTION pango_layout_set_alignment ##### --> +<para> + +</para> + +@layout: +@alignment: + + +<!-- ##### FUNCTION pango_layout_get_alignment ##### --> <para> </para> @layout: -@char_pos: +@Returns: + + +<!-- ##### ENUM PangoAlignment ##### --> +<para> +describes how to align the lines of a #PangoLayout within the +available space. If the #PangoLayout is set to justify +using pango_layout_set_justify(), then this only has an effect +for partial lines. +</para> + +@PANGO_ALIGN_LEFT: Put all available space on the right +@PANGO_ALIGN_CENTER: Center the line within the available space +@PANGO_ALIGN_RIGHT: Put all available space on the left + +<!-- ##### FUNCTION pango_layout_xy_to_index ##### --> +<para> + +</para> + +@layout: +@x: +@y: +@index: @trailing: -@line: -@x_pos: +@Returns: + + +<!-- ##### FUNCTION pango_layout_index_to_pos ##### --> +<para> + +</para> + +@layout: +@index: +@pos: + + +<!-- ##### FUNCTION pango_layout_get_extents ##### --> +<para> + +</para> + +@layout: +@ink_rect: +@logical_rect: <!-- ##### FUNCTION pango_layout_get_line_count ##### --> @@ -156,6 +227,42 @@ a #PangoLayoutLine. @Returns: +<!-- ##### FUNCTION pango_layout_get_lines ##### --> +<para> + +</para> + +@layout: +@Returns: + + +<!-- ##### STRUCT PangoLayoutLine ##### --> +<para> +The #PangoLayoutLine structure represents one of the lines resulting +from laying out a paragraph via #PangoLayout. #PangoLayoutLine +structures are obtained by calling pango_layout_get_line() and +are only valid until the text, attributes, or settings of the +parent #PangoLayout are modified. +</para> +<para> +Routines for rendering PangoLayout objects are provided in +code specific to each rendering system. +</para> + +@layout: the parent layout for this line. +@length: the length of the line in bytes. +@runs: a list containing the runs of the line in visual order. + +<!-- ##### STRUCT PangoLayoutRun ##### --> +<para> +The #PangoLayoutRun structure represents a single run within +a #PangoLayoutLine. +</para> + +@item: a #PangoItem structure that provides information + about the segment of text in this run. +@glyphs: the glyphs obtained by shaping the text for this item. + <!-- ##### FUNCTION pango_layout_line_ref ##### --> <para> @@ -172,24 +279,36 @@ a #PangoLayoutLine. @line: -<!-- ##### FUNCTION pango_layout_line_x_to_cp ##### --> +<!-- ##### FUNCTION pango_layout_line_get_extents ##### --> +<para> + +</para> + +@line: +@ink_rect: +@logical_rect: + + +<!-- ##### FUNCTION pango_layout_line_index_to_x ##### --> <para> </para> @line: -@x_pos: -@char_pos: +@index: @trailing: +@x_pos: -<!-- ##### FUNCTION pango_layout_line_get_extents ##### --> +<!-- ##### FUNCTION pango_layout_line_x_to_index ##### --> <para> </para> @line: -@ink_rect: -@logical_rect: +@x_pos: +@index: +@trailing: +@Returns: diff --git a/docs/tmpl/main.sgml b/docs/tmpl/main.sgml index 748419c4..b8e8617e 100644 --- a/docs/tmpl/main.sgml +++ b/docs/tmpl/main.sgml @@ -346,31 +346,3 @@ about the attributes of a single character. @min_kashida_width: -<!-- ##### FUNCTION pango_cp_to_x ##### --> -<para> - -</para> - -@text: -@length: -@analysis: -@glyphs: -@char_pos: -@trailing: -@x_pos: - - -<!-- ##### FUNCTION pango_x_to_cp ##### --> -<para> - -</para> - -@text: -@length: -@analysis: -@glyphs: -@x_pos: -@char_pos: -@trailing: - - diff --git a/docs/tmpl/pango-unused.sgml b/docs/tmpl/pango-unused.sgml index 376bf35b..6c16aa07 100644 --- a/docs/tmpl/pango-unused.sgml +++ b/docs/tmpl/pango-unused.sgml @@ -5,6 +5,27 @@ @font: +<!-- ##### FUNCTION pango_layout_line_x_to_cp ##### --> +<para> + +</para> + +@line: +@x_pos: +@char_pos: +@trailing: + +<!-- ##### FUNCTION pango_layout_cp_to_line_x ##### --> +<para> + +</para> + +@layout: +@char_pos: +@trailing: +@line: +@x_pos: + <!-- ##### FUNCTION pango_cfont_ref ##### --> <para> @@ -27,6 +48,34 @@ indices. @context: @Returns: +<!-- ##### FUNCTION pango_x_glyph_extents ##### --> +<para> + +</para> + +@font: +@glyph: +@lbearing: +@rbearing: +@width: +@ascent: +@descent: +@logical_ascent: +@logical_descent: + +<!-- ##### FUNCTION pango_cp_to_x ##### --> +<para> + +</para> + +@text: +@length: +@analysis: +@glyphs: +@char_pos: +@trailing: +@x_pos: + <!-- ##### FUNCTION pango_x_find_cfont ##### --> <para> @@ -78,6 +127,19 @@ indices. @xlfd: @Returns: +<!-- ##### FUNCTION pango_x_to_cp ##### --> +<para> + +</para> + +@text: +@length: +@analysis: +@glyphs: +@x_pos: +@char_pos: +@trailing: + <!-- ##### SECTION ./tmpl/pango-x.sgml:Title ##### --> X Rendering @@ -116,6 +178,14 @@ the X Window system. @Returns: +<!-- ##### FUNCTION pango_layout_set_first_line_width ##### --> +<para> + +</para> + +@layout: +@width: + <!-- ##### SECTION ./tmpl/pango-x.sgml:Long_Description ##### --> <para> @@ -220,3 +290,18 @@ that may be accessed by derived classes: @klass: +<!-- ##### FUNCTION pango_x_extents ##### --> +<para> + +</para> + +@font: +@glyphs: +@lbearing: +@rbearing: +@width: +@ascent: +@descent: +@logical_ascent: +@logical_descent: + diff --git a/docs/tmpl/x-rendering.sgml b/docs/tmpl/x-rendering.sgml index 3c4d10d7..82f0beea 100644 --- a/docs/tmpl/x-rendering.sgml +++ b/docs/tmpl/x-rendering.sgml @@ -2,11 +2,11 @@ X Rendering <!-- ##### SECTION Short_Description ##### --> -Functions for measuring glyphs and rendering X fonts. +Functions for Rendering Pango objects on X displays. <!-- ##### SECTION Long_Description ##### --> <para> -The functions in thjis system are used to take the output +The functions in this system are used to take the output of the shaping modules and render that on the screen. </para> @@ -47,35 +47,29 @@ X Window System. @y: -<!-- ##### FUNCTION pango_x_extents ##### --> +<!-- ##### FUNCTION pango_x_render_layout_line ##### --> <para> </para> -@font: -@glyphs: -@lbearing: -@rbearing: -@width: -@ascent: -@descent: -@logical_ascent: -@logical_descent: +@display: +@drawable: +@gc: +@line: +@x: +@y: -<!-- ##### FUNCTION pango_x_glyph_extents ##### --> +<!-- ##### FUNCTION pango_x_render_layout ##### --> <para> </para> -@font: -@glyph: -@lbearing: -@rbearing: -@width: -@ascent: -@descent: -@logical_ascent: -@logical_descent: +@display: +@drawable: +@gc: +@layout: +@x: +@y: diff --git a/examples/viewer.c b/examples/viewer.c index 0ff8a503..b4c971d1 100644 --- a/examples/viewer.c +++ b/examples/viewer.c @@ -142,10 +142,10 @@ split_paragraphs (char *text) Paragraph *para = g_new (Paragraph, 1); para->text = last_para; para->length = p - last_para; - para->height = 0; para->layout = pango_layout_new (context); pango_layout_set_text (para->layout, para->text, para->length); - + para->height = 0; + last_para = next; result = g_list_prepend (result, para); @@ -158,42 +158,15 @@ split_paragraphs (char *text) return g_list_reverse (result); } -/* Break a paragraph into a list of lines which fit into - * width, and compute the total height of the new paragraph - */ -void -layout_paragraph (Paragraph *para, int width) -{ - GSList *line_list; - PangoRectangle logical_rect; - int height = 0; - - pango_layout_set_width (para->layout, width * 1000); - pango_layout_set_first_line_width (para->layout, width * 1000); - - line_list = pango_layout_get_lines (para->layout); - while (line_list) - { - PangoLayoutLine *line = line_list->data; - line_list = line_list->next; - - pango_layout_line_get_extents (line, NULL, &logical_rect); - height += logical_rect.height; - } - - para->height = height / 1000; -} - /* Given an x-y position, return the paragraph and offset * within the paragraph of the click. */ gboolean xy_to_cp (GList *paragraphs, int width, int x, int y, - Paragraph **para_return, int *offset) + Paragraph **para_return, int *index) { GList *para_list; int height = 0; - PangoDirection base_dir = pango_context_get_base_dir (context); *para_return = NULL; @@ -204,38 +177,12 @@ xy_to_cp (GList *paragraphs, int width, int x, int y, if (height + para->height >= y) { - PangoRectangle logical_rect; - GSList *line_list = pango_layout_get_lines (para->layout); - - while (line_list) - { - PangoLayoutLine *line = line_list->data; - int line_y = (y - height) * 1000; - int line_height = 0; - - pango_layout_line_get_extents (line_list->data, NULL, &logical_rect); - - if (line_height + logical_rect.height >= line_y) - { - int x_offset; - - if (base_dir == PANGO_DIRECTION_RTL) - x_offset = width - logical_rect.width / 1000; - else - x_offset = 0; - - if (pango_layout_line_x_to_index (line, 1000 * (x - x_offset), offset, NULL)) - { - *para_return = para; - return TRUE; - } - else - return FALSE; - } - - line_height += logical_rect.height; - line_list = line_list->next; - } + gboolean result = pango_layout_xy_to_index (para->layout, x * 1000, (y - height) * 1000, + index, NULL); + if (result && para_return) + *para_return = para; + + return result; } height += para->height; @@ -255,8 +202,6 @@ char_bounds (GList *paragraphs, Paragraph *para, int index, GList *para_list; int height = 0; - int bytes_seen = 0; - PangoDirection base_dir = pango_context_get_base_dir (context); para_list = paragraphs; while (para_list) @@ -265,47 +210,14 @@ char_bounds (GList *paragraphs, Paragraph *para, int index, if (cur_para == para) { - int line_height = 0; - - GSList *line_list = pango_layout_get_lines (para->layout); - while (line_list) - { - PangoLayoutLine *line = line_list->data; - PangoRectangle logical_rect; - - pango_layout_line_get_extents (line_list->data, NULL, &logical_rect); - - bytes_seen += line->length; - if (index < bytes_seen) - { - int x0, x1; - - pango_layout_line_index_to_x (line, index, FALSE, &x0); - pango_layout_line_index_to_x (line, index, TRUE, &x1); - - if (x0 <= x1) - { - rect->x = x0 / 1000; - rect->width = (x1 / 1000) - rect->x; - } - else - { - rect->x = x1 / 1000; - rect->width = (x0 / 1000) - rect->x; - } - - rect->y = height + line_height / 1000; - rect->height = logical_rect.height / 1000; - - if (base_dir == PANGO_DIRECTION_RTL) - rect->x += width - logical_rect.width / 1000; - - return; - } - - line_height += logical_rect.height; - line_list = line_list->next; - } + PangoRectangle pos; + + pango_layout_index_to_pos (cur_para->layout, index, &pos); + + rect->x = MIN (pos.x, pos.x + pos.width) / 1000; + rect->width = ABS (pos.width) / 1000; + rect->y = height + pos.y / 1000; + rect->height = pos.height / 1000; } height += cur_para->height; @@ -345,39 +257,6 @@ xor_char (GtkWidget *layout, GdkRectangle *clip_rect, rect.x, rect.y, rect.width, rect.height); } - -/* Draw a paragraph on the screen by looping through the list - * of lines, then for each line, looping through the list of - * runs for that line and drawing them. - */ -void -expose_paragraph (Paragraph *para, GdkDrawable *drawable, - GdkGC *gc, int width, int x, int y) -{ - GSList *line_list; - int line_height = 0; - PangoRectangle logical_rect; - PangoDirection base_dir = pango_context_get_base_dir (context); - - line_list = pango_layout_get_lines (para->layout); - while (line_list) - { - PangoLayoutLine *line = line_list->data; - line_list = line_list->next; - - pango_layout_line_get_extents (line, NULL, &logical_rect); - - if (base_dir == PANGO_DIRECTION_LTR) - pango_x_render_layout_line (GDK_DISPLAY(), GDK_WINDOW_XWINDOW (drawable), GDK_GC_XGC (gc), - line, x, y + line_height / 1000); - else - pango_x_render_layout_line (GDK_DISPLAY(), GDK_WINDOW_XWINDOW (drawable), GDK_GC_XGC (gc), - line, x + width - logical_rect.width / 1000, y + line_height / 1000); - - line_height += logical_rect.height; - } -} - /* Handle a size allocation by re-laying-out each paragraph to * the new width, setting the new size for the layout and * then queing a redraw @@ -387,14 +266,22 @@ size_allocate (GtkWidget *layout, GtkAllocation *allocation, GList *paragraphs) { GList *tmp_list; int height = 0; + PangoDirection base_dir = pango_context_get_base_dir (context); tmp_list = paragraphs; while (tmp_list) { Paragraph *para = tmp_list->data; + PangoRectangle logical_rect; + tmp_list = tmp_list->next; - layout_paragraph (para, allocation->width); + pango_layout_set_alignment (para->layout, + base_dir == PANGO_DIRECTION_LTR ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT); + pango_layout_set_width (para->layout, layout->allocation.width * 1000); + + pango_layout_get_extents (para->layout, NULL, &logical_rect); + para->height = logical_rect.height / 1000; height += para->height; } @@ -402,8 +289,7 @@ size_allocate (GtkWidget *layout, GtkAllocation *allocation, GList *paragraphs) gtk_layout_set_size (GTK_LAYOUT (layout), allocation->width, height); if (GTK_LAYOUT (layout)->yoffset + allocation->height > height) - gtk_adjustment_set_value (GTK_LAYOUT (layout)->vadjustment, - height - allocation->height); + gtk_adjustment_set_value (GTK_LAYOUT (layout)->vadjustment, height - allocation->height); } /* Handle a draw/expose by finding the paragraphs that intersect @@ -431,12 +317,10 @@ draw (GtkWidget *layout, GdkRectangle *area, GList *paragraphs) tmp_list = tmp_list->next; if (height + para->height >= GTK_LAYOUT (layout)->yoffset + area->y) - expose_paragraph (para, - GTK_LAYOUT (layout)->bin_window, - layout->style->text_gc[layout->state], - layout->allocation.width, - 0, height - GTK_LAYOUT (layout)->yoffset); - + pango_x_render_layout (GDK_DISPLAY(), GDK_WINDOW_XWINDOW (GTK_LAYOUT (layout)->bin_window), + GDK_GC_XGC (layout->style->text_gc[GTK_STATE_NORMAL]), + para->layout, 0, height - GTK_LAYOUT (layout)->yoffset); + height += para->height; } diff --git a/modules/arabic/.cvsignore b/modules/arabic/.cvsignore new file mode 100644 index 00000000..6e5ca7ed --- /dev/null +++ b/modules/arabic/.cvsignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.deps +.libs +*.lo +*.la diff --git a/modules/arabic/arabic-x.c b/modules/arabic/arabic-x.c index 58875d58..18ee4ce1 100644 --- a/modules/arabic/arabic-x.c +++ b/modules/arabic/arabic-x.c @@ -136,10 +136,16 @@ set_glyph (PangoGlyphString *glyphs, glyphs->glyphs[i].geometry.x_offset = 0; glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->log_clusters[i] = cluster_start; - pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect); - glyphs->glyphs[i].geometry.width = logical_rect.width; + glyphs->log_clusters[i] = cluster_start; + if (arabic_isvowel(glyph)) + { + glyphs->glyphs[i].geometry.width = 0; + } + else + { + glyphs->glyphs[i].geometry.width = logical_rect.width; + } } @@ -157,6 +163,7 @@ arabic_engine_shape (PangoFont *font, int n_chars, n_glyph; int i; const char *p; + const char *pold; const char *next; GUChar4 *wc; @@ -189,7 +196,8 @@ arabic_engine_shape (PangoFont *font, if (analysis->level % 2 == 0) { - /* We somehow were called on a LTR directional run; fallback as simply as possible */ + /* We were called on a LTR directional run (e.g. some numbers); + fallback as simply as possible */ pango_glyph_string_set_size (glyphs, n_chars); @@ -215,62 +223,40 @@ arabic_engine_shape (PangoFont *font, p = next; } - reshape(n_chars,wc); - - /* The following support for ALIF.LAM ligatures is hackish and should - * be moved into arconv.c. (As a rough guess, arconv.c should fill - * in a log_clusters[] type array with character offets, that would - * then convert to the byte offsets needed for the real log_clusters[]) - * - * The ligature detection below is written in terms of the Unicode - * presentation forms, which is almost certainly not the right way - * to do things. - */ - -#define ALIF_R 0xFE8E -#define LAM_L 0xFEDF -#define LAM_M 0xFEE0 -#define ALIF_LAM_R 0xFEFC -#define ALIF_LAM_N 0xFEFB - for (i = n_chars - 1; i >= 1; i--) - { - if (wc[i-1] == ALIF_R && (wc[i] == LAM_M || wc[i] == LAM_L)) - n_glyph--; - } + reshape(&n_glyph,wc); +/* raise(2); */ pango_glyph_string_set_size (glyphs, n_glyph); - p = text; - for (i = n_chars - 1; i >= 0; i--) + p = text; + pold = p; + i = n_chars-1; + while(i >= 0) { - int ligature = 0; - - if (i > 0) - { - if (wc[i-1] == ALIF_R && wc[i] == LAM_M) - { - ligature = ALIF_LAM_R; - } - else if (wc[i-1] == ALIF_R && wc[i] == LAM_L) - { - ligature = ALIF_LAM_N; - } - } - - if (ligature != 0) - { - set_glyph (glyphs, font, subfont, n_glyph - 1, p - text, ligature); - p = unicode_next_utf8 (p); - i--; - } - else - set_glyph (glyphs, font, subfont, n_glyph - 1, p - text, wc[i]); + if (wc[i] == 0) + { + p = unicode_next_utf8 (p); + i--; + } + else + { + set_glyph (glyphs, font, subfont, n_glyph - 1, p - text, wc[i]); + if ( arabic_isvowel(wc[i])) + { + glyphs->log_clusters[n_glyph-1] = pold - text; + } - p = unicode_next_utf8 (p); - n_glyph--; - }; + pold = p; + p = unicode_next_utf8 (p); + n_glyph--; + i--; + }; + } +/* if ((i != 0)||(n_glyph-1 != 0)){ */ +/* printf(" i= %x , n_glyph = %x "); */ +/* }; */ g_free(wc); } diff --git a/modules/arabic/arabic.c b/modules/arabic/arabic.c index 58875d58..18ee4ce1 100644 --- a/modules/arabic/arabic.c +++ b/modules/arabic/arabic.c @@ -136,10 +136,16 @@ set_glyph (PangoGlyphString *glyphs, glyphs->glyphs[i].geometry.x_offset = 0; glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->log_clusters[i] = cluster_start; - pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect); - glyphs->glyphs[i].geometry.width = logical_rect.width; + glyphs->log_clusters[i] = cluster_start; + if (arabic_isvowel(glyph)) + { + glyphs->glyphs[i].geometry.width = 0; + } + else + { + glyphs->glyphs[i].geometry.width = logical_rect.width; + } } @@ -157,6 +163,7 @@ arabic_engine_shape (PangoFont *font, int n_chars, n_glyph; int i; const char *p; + const char *pold; const char *next; GUChar4 *wc; @@ -189,7 +196,8 @@ arabic_engine_shape (PangoFont *font, if (analysis->level % 2 == 0) { - /* We somehow were called on a LTR directional run; fallback as simply as possible */ + /* We were called on a LTR directional run (e.g. some numbers); + fallback as simply as possible */ pango_glyph_string_set_size (glyphs, n_chars); @@ -215,62 +223,40 @@ arabic_engine_shape (PangoFont *font, p = next; } - reshape(n_chars,wc); - - /* The following support for ALIF.LAM ligatures is hackish and should - * be moved into arconv.c. (As a rough guess, arconv.c should fill - * in a log_clusters[] type array with character offets, that would - * then convert to the byte offsets needed for the real log_clusters[]) - * - * The ligature detection below is written in terms of the Unicode - * presentation forms, which is almost certainly not the right way - * to do things. - */ - -#define ALIF_R 0xFE8E -#define LAM_L 0xFEDF -#define LAM_M 0xFEE0 -#define ALIF_LAM_R 0xFEFC -#define ALIF_LAM_N 0xFEFB - for (i = n_chars - 1; i >= 1; i--) - { - if (wc[i-1] == ALIF_R && (wc[i] == LAM_M || wc[i] == LAM_L)) - n_glyph--; - } + reshape(&n_glyph,wc); +/* raise(2); */ pango_glyph_string_set_size (glyphs, n_glyph); - p = text; - for (i = n_chars - 1; i >= 0; i--) + p = text; + pold = p; + i = n_chars-1; + while(i >= 0) { - int ligature = 0; - - if (i > 0) - { - if (wc[i-1] == ALIF_R && wc[i] == LAM_M) - { - ligature = ALIF_LAM_R; - } - else if (wc[i-1] == ALIF_R && wc[i] == LAM_L) - { - ligature = ALIF_LAM_N; - } - } - - if (ligature != 0) - { - set_glyph (glyphs, font, subfont, n_glyph - 1, p - text, ligature); - p = unicode_next_utf8 (p); - i--; - } - else - set_glyph (glyphs, font, subfont, n_glyph - 1, p - text, wc[i]); + if (wc[i] == 0) + { + p = unicode_next_utf8 (p); + i--; + } + else + { + set_glyph (glyphs, font, subfont, n_glyph - 1, p - text, wc[i]); + if ( arabic_isvowel(wc[i])) + { + glyphs->log_clusters[n_glyph-1] = pold - text; + } - p = unicode_next_utf8 (p); - n_glyph--; - }; + pold = p; + p = unicode_next_utf8 (p); + n_glyph--; + i--; + }; + } +/* if ((i != 0)||(n_glyph-1 != 0)){ */ +/* printf(" i= %x , n_glyph = %x "); */ +/* }; */ g_free(wc); } diff --git a/modules/arabic/arconv.c b/modules/arabic/arconv.c index aa612353..c345e3a8 100644 --- a/modules/arabic/arconv.c +++ b/modules/arabic/arconv.c @@ -12,6 +12,7 @@ typedef struct { static shapestruct chartable [] = { + {0x621, 0xFE80,4}, /* HAMZA; handle seperately !!! */ {0x622, 0xFE81,2}, /* ALIF MADDA */ {0x623, 0xFE83,2}, /* ALIF HAMZA */ {0x624, 0xFE85,2}, /* WAW HAMZA */ @@ -47,15 +48,46 @@ static shapestruct chartable [] = {0x648, 0xFEED,2}, /* WAW */ {0x649, 0xFEEF,2}, /* ALIF MAQSORA */ {0x64A, 0xFEF1,4}, /* YA */ - {0x66D, 0xFEF5,2} /* star,LAM-ALIF */ + {0xFEF5, 0xFEF5,2}, /* Lam-Alif Madda */ + {0xFEF7, 0xFEF7,2}, /* Lam-Alif Hamza*/ + {0xFEF9, 0xFEF9,2}, /* Lam-Alif iHamza*/ + {0xFEFB, 0xFEFB,2} /* Lam-Alif */ }; +#define ALIF 0x627 +#define ALIFHAMZA 0x623 +#define ALIFIHAMZA 0x625 +#define ALIFMADDA 0x622 +#define LAM 0x644 +#define HAMZA 0x621 +#define WAW 0x648 +#define WAWHAMZA 0x624 + + +#define LAM_ALIF 0xFEFB +#define LAM_ALIFHAMZA 0xFEF7 +#define LAM_ALIFIHAMZA 0xFEF9 +#define LAM_ALIFMADDA 0xFEF5 + +#define LAM_ALIF_f 0xFEFC +#define LAM_ALIFHAMZA_f 0xFEF8 +#define LAM_ALIFIHAMZA_f 0xFEFA +#define LAM_ALIFMADDA_f 0xFEF6 + +int arabic_isvowel(GUChar4 s) +{ + if ((s >= 0x64B) && (s <= 0x653)) return 1; + if ((s >= 0xFE70) && (s <= 0xFE7F)) return 1; + return 0; +} static GUChar4 unshape(GUChar4 s) { int j = 0; - if ( (s > 0xFE80) && ( s < 0xFEFF )){ /* arabic shaped Glyph */ + if ( (s > 0xFE80) && ( s < 0xFEFF )){ /* arabic shaped Glyph , not HAMZA */ while ( chartable[j+1].charstart <= s) j++; return chartable[j].basechar; + } else if ((s == 0xFE8B)||(s == 0xFE8C)){ + return HAMZA; } else { return s; }; @@ -64,9 +96,13 @@ static GUChar4 unshape(GUChar4 s) static GUChar4 charshape(GUChar4 s,short which) { /* which 0=alone 1=end 2=start 3=middle */ int j = 0; - if ( (s >= 0x622) && ( s <= 0x64A )){ /* arabic base char */ + if ( (s >= chartable[1].basechar) && ( s <= 0xFEFB )){ + /* arabic base char of Lam-Alif */ while ( chartable[j].basechar < s) j++; return chartable[j].charstart+which; + } else if (s == HAMZA){ + if (which < 2) return s; + else return 0xFE8B+(which-2); /* The Hamza-'pod' */ } else { return s; }; @@ -76,61 +112,122 @@ static GUChar4 charshape(GUChar4 s,short which) static short shapecount(GUChar4 s) { int j = 0; - if ( (s >= 0x622) && ( s <= 0x64A )){ /* arabic base char */ - while ( chartable[j].basechar < s) j++; - return chartable[j].count; + if (arabic_isvowel(s)){ /* correct trailing wovels */ + return 1; + } else if ( (s >= chartable[0].basechar) && ( s <= 0xFEFB )){ + /* arabic base char or ligature */ + while ( chartable[j].basechar < s) j++; + return chartable[j].count; } else { - return 1; + return 1; }; } -void shape(int len,GUChar4* string) +void shape(int* len,GUChar4* string) { /* The string must be in visual order already. ** This routine does the basic arabic reshaping. */ int j; + int pcount = 1; /* #of preceding vowels , plus one */ short nc; /* #shapes of next char */ short sc; /* #shapes of current char */ int prevstate = 0; /* */ int which; - sc = shapecount(string[len-1]); - for ( j = len-1; j >= 0; j-- ){ + GUChar4 prevchar = 0; + + sc = shapecount(string[(*len)-1]); + j = (*len)-1; + while (j >= 0){ + if (arabic_isvowel(string[j])){ + j--; continue; /* don't shape vowels */ + } + if (string[j] == 0){ + j--; continue; + }; if (j > 0){ - nc = shapecount(string[j-1]); + pcount = 1; + while ( ( j-pcount >= 0)&& + ( (arabic_isvowel(string[j-pcount]))|| + (string[j-pcount] == 0) )) + pcount++; + nc = shapecount(string[j-pcount]); } else { - nc = 1; + nc = 1; }; - - if ( prevstate & 2 ){ /* use and end or Middle-form */ - if (nc == 1){ - which = 1; /* end */ - } else { - which = 3; /* middle */ - } - } else { /* use a stand-alone or beginning-form */ - if (nc == 1){ - which = 0; /* basic */ - } else { - which = 2; /* beginning */ - } + + if (nc == 1){ + which = 0; /* end or basic */ + } else { + which = 2; /* middle or beginning */ }; + if ( prevstate & 2 ){ /* use end or Middle-form */ + which += 1; +#define LIG +#ifdef LIG + /* test if char == Alif && prev == Lam */ + if (prevchar == LAM){ + switch(string[j]){ + case ALIF: + (*len)--; + string[j+1] = LAM_ALIF; + string[j] = 0; j++; break; + case ALIFHAMZA: + (*len)--; + string[j+1] = LAM_ALIFHAMZA; + string[j] = 0; j++; break; + case ALIFIHAMZA: + (*len)--; + string[j+1] = LAM_ALIFIHAMZA; + string[j] = 0; j++; break; + case ALIFMADDA: + (*len)--; + string[j+1] = LAM_ALIFMADDA; + string[j] = 0; j++; break; + } + } +#endif + } else { /* use basic or beginning form */ +#ifdef LIG + if ((string[j] == HAMZA) + &&(prevchar) + &&(!arabic_isvowel(string[j-1])) ){ + switch(prevchar){ + case ALIF: + (*len)--; + string[j+1] = ALIFHAMZA; + string[j] = 0; + j++; sc = 2; break; + case WAW: + (*len)--; + string[j+1] = WAWHAMZA; + string[j] = 0; + j++; sc = 2; break; + /* case LAM_ALIF: have to hande LAM_ALIF+HAMZA.*/ + /* But LAM_ALIF is two back already ... */ + } + } +#endif + } which = which % sc; /* middle->end,beginning->basic */ - string[j] = charshape(string[j],which); - prevstate = which; - sc = nc; /* no need to recalculate */ + if (string[j] != 0){ + prevchar = string[j]; + string[j] = charshape(string[j],which); + prevstate = which; + sc = nc; /* no need to recalculate */ + } + j--; } } -void reshape(int len,GUChar4* string) +void reshape(int* len,GUChar4* string) { int i; - for ( i = 0; i < len; i++){ + for ( i = 0; i < *len; i++){ string[i] = unshape(string[i]); } shape(len,string); } /* Lam-Alif beginns at F5,F7,F9,FB ( MADDA,HAMZA,IHAMZA, . respectively ) */ - diff --git a/modules/arabic/arconv.h b/modules/arabic/arconv.h index bc3d3300..89c72b7d 100644 --- a/modules/arabic/arconv.h +++ b/modules/arabic/arconv.h @@ -3,6 +3,7 @@ #define __arconv_h_ #include "../../libpango/utils.h" -void reshape(int len,GUChar4* string); +void reshape(int* len,GUChar4* string); +int arabic_isvowel(GUChar4 s); #endif diff --git a/pango/fonts.c b/pango/fonts.c index 9ff5d7d6..5b74a0f7 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -469,7 +469,6 @@ pango_font_get_coverage (PangoFont *font, const char *lang) { g_return_val_if_fail (font != NULL, NULL); - g_return_val_if_fail (lang != NULL, NULL); return font->klass->get_coverage (font, lang); } @@ -491,7 +490,6 @@ pango_font_find_shaper (PangoFont *font, guint32 ch) { g_return_val_if_fail (font != NULL, NULL); - g_return_val_if_fail (lang != NULL, NULL); return font->klass->find_shaper (font, lang, ch); } diff --git a/pango/modules.c b/pango/modules.c index f2433ca8..fe8ef52d 100644 --- a/pango/modules.c +++ b/pango/modules.c @@ -76,7 +76,7 @@ _pango_find_map (const char *lang, if (!map) { PangoMapInfo *new_info = g_new (PangoMapInfo, 1); - new_info->lang = g_strdup (lang); + new_info->lang = g_strdup (map_info.lang); new_info->engine_type = g_strdup (engine_type); new_info->render_type = g_strdup (render_type); diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 04b440df..19b532fd 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -36,7 +36,10 @@ struct _PangoLayout gchar *text; int length; /* length of text in bytes */ int width; /* wrap width, in device units */ - int first_line_width; /* wrap width for first line, in device units */ + int indent; /* amount by which first line should be shorter */ + + guint justify : 1; + guint alignment : 2; GSList *lines; }; @@ -80,7 +83,10 @@ pango_layout_new (PangoContext *context) layout->text = NULL; layout->length = 0; layout->width = -1; - layout->first_line_width = -1; + layout->indent = 0; + + layout->alignment = PANGO_ALIGN_LEFT; + layout->justify = FALSE; layout->lines = NULL; @@ -135,7 +141,7 @@ pango_layout_unref (PangoLayout *layout) * @width: the desired width, or -1 to indicate that no wrapping should be * performed. * - * Set the width to which the lines of the #PangoLayout should be wrapped. + * Sets the width to which the lines of the #PangoLayout should be wrapped. **/ void pango_layout_set_width (PangoLayout *layout, @@ -148,35 +154,70 @@ pango_layout_set_width (PangoLayout *layout, } /** - * pango_layout_set_first_width: + * pango_layout_get_width: + * @layout: a #PangoLayout + * + * Gets the width to which the lines of the #PangoLayout should be wrapped. + * + * Return value: the width + **/ +int +pango_layout_get_width (PangoLayout *layout) +{ + g_return_val_if_fail (layout != NULL, 0); + return layout->width; +} + +/** + * pango_layout_set_indent * @layout: a #PangoLayout. - * @width: the desired width, or -1 to indicate that it should be the same - * as the the width set by pango_layout_set_width(). + * @indent: the amount by which to indent * - * Set the width to which the first line of the #PangoLayout should be - * wrapped. + * Sets the amount by which the first line should be shorter than the + * rest of the lines. This may be negative, in which case + * the subsequent lines will be shorter than the first line. (However, + * in either case, the entire width of the layout will be given by + * the value **/ void -pango_layout_set_first_line_width (PangoLayout *layout, - int width) +pango_layout_set_indent (PangoLayout *layout, + int indent) { g_return_if_fail (layout != NULL); - layout->first_line_width = width; + layout->indent = indent; pango_layout_clear_lines (layout); } /** + * pango_layout_get_indent: + * @layout: a #PangoLayout + * + * Gets the amount by which the first line should be shorter than the + * rest of the lines. + * + * Return value: the indent + **/ +int +pango_layout_get_indent (PangoLayout *layout) +{ + g_return_val_if_fail (layout != NULL, 0); + return layout->indent; +} + +/** * pango_layout_set_attributes: * @layout: a #PangoLayout * @attrs: a #PangoAttrList * - * Set the text attributes for a layout object + * Sets the text attributes for a layout object **/ void -pango_layout_set_attributes (PangoLayout *layout, - PangoAttrList *attrs) +pango_layout_set_attributes (PangoLayout *layout, + PangoAttrList *attrs) { + g_return_if_fail (layout != NULL); + if (layout->attrs) pango_attr_list_unref (layout->attrs); @@ -186,6 +227,74 @@ pango_layout_set_attributes (PangoLayout *layout, } /** + * pango_layout_set_justify: + * @layout: a #PangoLayout + * @justify: whether the lines in the layout should be justified. + * + * Sets whether or not each complete line should be stretched to + * fill the entire width of the layout. This stretching is typically + * done by adding whitespace, but for some scripts (such as Arabic), + * the justification is done by extending the characters. + **/ +void +pango_layout_set_justify (PangoLayout *layout, + gboolean justify) +{ + g_return_if_fail (layout != NULL); + + layout->justify = justify; +} + +/** + * pango_layout_get_justify: + * @layout: a #PangoLayout + * + * Gets whether or not each complete line should be stretched to + * fill the entire width of the layout. + * + * Return value: the justify + **/ +gboolean +pango_layout_get_justify (PangoLayout *layout) +{ + g_return_val_if_fail (layout != NULL, FALSE); + return layout->justify; +} + +/** + * pango_layout_set_alignment: + * @layout: a #PangoLayout + * @alignment: the new alignment + * + * Sets the alignment for the layout (how partial lines are + * positioned within the horizontal space available.) + **/ +void +pango_layout_set_alignment (PangoLayout *layout, + PangoAlignment alignment) +{ + g_return_if_fail (layout != NULL); + + layout->alignment = alignment; +} + +/** + * pango_layout_get_alignment: + * @layout: a #PangoLayout + * + * Sets the alignment for the layout (how partial lines are + * positioned within the horizontal space available.) + * + * Return value: the alignment value + **/ +PangoAlignment +pango_layout_get_alignment (PangoLayout *layout) +{ + g_return_val_if_fail (layout != NULL, PANGO_ALIGN_LEFT); + return layout->alignment; +} + +/** * pango_layout_set_text: * @layout: a #PangoLayout * @text: a UTF8-string @@ -231,7 +340,6 @@ pango_layout_get_line_count (PangoLayout *layout) g_return_val_if_fail (layout != NULL, 0); pango_layout_check_lines (layout); - return g_slist_length (layout->lines); } @@ -259,7 +367,7 @@ pango_layout_get_lines (PangoLayout *layout) * @line: the index of a line, which must be between 0 and * pango_layout_get_line_count(layout) - 1, inclusive. * - * Retrieve a particular line from a #PangoLayout + * Retrieves a particular line from a #PangoLayout * * Return value: the requested #PangoLayoutLine, or %NULL if the * index is out of range. This layout line can @@ -357,7 +465,7 @@ pango_layout_index_to_line_x (PangoLayout *layout, int tmp_line = 0; int bytes_seen = 0; - g_return_if_fail (line != NULL); + g_return_if_fail (layout != NULL); pango_layout_check_lines (layout); @@ -385,6 +493,230 @@ pango_layout_index_to_line_x (PangoLayout *layout, *x_pos = -1; } +/** + * pango_layout_xy_to_index: + * @layout: a #PangoLayout + * @x: the X offset (in thousandths of a device unit) + * from the left edge of the layout. + * @y: the Y offset (in thousandths of a device unit) + * from the top edge of the layout + * @index: location to store calculated byte index + * @trailing: location to store a integer indicating where + * in the cluster the user clicked. If the script + * allows positioning within the cluster, it is either + * 0 or 1; otherwise it is either 0 or the number + * of characters in the cluster. In either case + * 0 represents the trailing edge of the cluster. + * + * Convert from X and Y position within a layout to the byte + * offset to the character at that logical position. + * + * Return value: TRUE if the position was within the layout + **/ +gboolean +pango_layout_xy_to_index (PangoLayout *layout, + int x, + int y, + int *index, + gboolean *trailing) +{ + GSList *line_list; + int y_offset = 0; + + g_return_val_if_fail (layout != NULL, FALSE); + + pango_layout_check_lines (layout); + + line_list = layout->lines; + while (line_list) + { + PangoLayoutLine *line = line_list->data; + PangoRectangle logical_rect; + + pango_layout_line_get_extents (line, NULL, &logical_rect); + + if (y_offset + logical_rect.height >= y) + { + int x_offset; + + if (layout->width != 1 && layout->alignment == PANGO_ALIGN_RIGHT) + x_offset = layout->width - logical_rect.width; + else if (layout->width != 1 && layout->alignment == PANGO_ALIGN_CENTER) + x_offset = (layout->width - logical_rect.width) / 2; + else + x_offset = 0; + + return pango_layout_line_x_to_index (line, x - x_offset, index, trailing); + } + + y_offset += logical_rect.height; + line_list = line_list->next; + } + + return FALSE; +} + +/** + * pango_layout_index_to_pos: + * @layout: a #PangoLayout + * @index: byte index within @layout + * @pos: rectangle in which to store the position of the character + * + * Convert from an index within a PangoLayout to the onscreen position + * corresponding to that character, which is represented as rectangle. + * Note that pos->x is always the leading edge of the character. If the + * and pos->x + pos->width the trailing edge of the character. If the + * directionality of the character is right-to-left, then pos->width + * will be negative. + **/ +void +pango_layout_index_to_pos (PangoLayout *layout, + int index, + PangoRectangle *pos) +{ + PangoRectangle logical_rect; + GSList *tmp_list; + int bytes_seen = 0; + + g_return_if_fail (layout != NULL); + g_return_if_fail (index >= 0 && index < layout->length); + + pos->y = 0; + + pango_layout_check_lines (layout); + + tmp_list = layout->lines; + while (tmp_list) + { + PangoLayoutLine *layout_line = tmp_list->data; + + pango_layout_line_get_extents (layout_line, NULL, &logical_rect); + + if (bytes_seen + layout_line->length > index) + { + int x_pos; + int x_offset; + + if (layout->width != 1 && layout->alignment == PANGO_ALIGN_RIGHT) + x_offset = layout->width - logical_rect.width; + else if (layout->width != 1 && layout->alignment == PANGO_ALIGN_CENTER) + x_offset = (layout->width - logical_rect.width) / 2; + else + x_offset = 0; + + pos->height = logical_rect.height; + + pango_layout_line_index_to_x (layout_line, index, FALSE, &x_pos); + pos->x = x_pos; + + pango_layout_line_index_to_x (layout_line, index, TRUE, &x_pos); + pos->width = x_pos - pos->x; + + pos->x += x_offset; + + return; + } + + tmp_list = tmp_list->next; + bytes_seen += layout_line->length; + pos->y += logical_rect.height; + } +} + +/** + * pango_layout_get_extents: + * @layout: a #PangoLayout + * @ink_rect: rectangle used to store the extents of the glyph string as drawn + * or %NULL to indicate that the result is not needed. + * @logical_rect: rectangle used to store the logical extents of the glyph string + * or %NULL to indicate that the result is not needed. + * + * Compute the logical and ink extents of a layout line. See the documentation + * for pango_font_get_glyph_extents() for details about the interpretation + * of the rectangles. + */ +void +pango_layout_get_extents (PangoLayout *layout, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + GSList *line_list; + int y_offset = 0; + + g_return_if_fail (layout != NULL); + + pango_layout_check_lines (layout); + + line_list = layout->lines; + while (line_list) + { + PangoLayoutLine *line = line_list->data; + PangoRectangle line_ink; + PangoRectangle line_logical; + + int x_offset; + int new_pos; + + pango_layout_line_get_extents (line, ink_rect ? &line_ink : NULL, &line_logical); + + if (layout->width != 1 && layout->alignment == PANGO_ALIGN_RIGHT) + x_offset = layout->width - line_logical.width; + else if (layout->width != 1 && layout->alignment == PANGO_ALIGN_CENTER) + x_offset = (layout->width - line_logical.width) / 2; + else + x_offset = 0; + + if (ink_rect) + { + if (line_list == layout->lines) + { + ink_rect->x = line_ink.x + x_offset; + ink_rect->y = line_ink.y; + ink_rect->width = line_ink.width; + ink_rect->height = line_ink.height; + } + else + { + new_pos = MIN (ink_rect->x, line_ink.x + x_offset); + ink_rect->width = MAX (ink_rect->x + ink_rect->width, + line_ink.x + line_ink.width + x_offset) - new_pos; + ink_rect->x = new_pos; + + new_pos = MIN (ink_rect->y, line_ink.y + y_offset); + ink_rect->height = MAX (ink_rect->y + ink_rect->height, + line_ink.y + line_ink.height + y_offset) - new_pos; + ink_rect->y = new_pos; + } + } + + if (logical_rect) + { + if (line_list == layout->lines) + { + logical_rect->x = line_logical.x + x_offset; + logical_rect->y = line_logical.y; + logical_rect->width = line_logical.width; + logical_rect->height = line_logical.height; + } + else + { + new_pos = MIN (logical_rect->x, line_logical.x + x_offset); + logical_rect->width = MAX (logical_rect->x + logical_rect->width, + line_logical.x + line_logical.width + x_offset) - new_pos; + logical_rect->x = new_pos; + + new_pos = MIN (logical_rect->y, line_logical.y + y_offset); + logical_rect->height = MAX (logical_rect->y + logical_rect->height, + line_logical.y + line_logical.height + y_offset) - new_pos; + logical_rect->y = new_pos; + } + } + + y_offset += line_logical.height; + line_list = line_list->next; + } +} + static void pango_layout_clear_lines (PangoLayout *layout) { @@ -531,7 +863,7 @@ pango_layout_check_lines (PangoLayout *layout) return; line = pango_layout_line_new (layout); - remaining_width = layout->first_line_width; + remaining_width = (layout->indent >= 0) ? layout->width - layout->indent : layout->indent; /* FIXME, should we force people to set the attrs? */ if (layout->attrs) @@ -565,7 +897,7 @@ pango_layout_check_lines (PangoLayout *layout) layout->lines = g_slist_prepend (layout->lines, line); line = pango_layout_line_new (layout); - remaining_width = layout->width; + remaining_width = (layout->indent >= 0) ? layout->width : layout->indent + layout->indent; } } @@ -596,7 +928,7 @@ pango_layout_line_ref (PangoLayoutLine *line) /** * pango_layout_line_unref: - * @line: + * @line: a #PangoLayoutLine * * Decrease the reference count of a #PangoLayoutLine by one. * if the result is zero, the line and all associated memory diff --git a/pango/pango-layout.h b/pango/pango-layout.h index 75e82bad..ecc5b631 100644 --- a/pango/pango-layout.h +++ b/pango/pango-layout.h @@ -34,6 +34,12 @@ typedef struct _PangoLayout PangoLayout; typedef struct _PangoLayoutLine PangoLayoutLine; typedef struct _PangoLayoutRun PangoLayoutRun; +typedef enum { + PANGO_ALIGN_LEFT, + PANGO_ALIGN_CENTER, + PANGO_ALIGN_RIGHT +} PangoAlignment; + struct _PangoLayoutLine { PangoLayout *layout; @@ -47,29 +53,47 @@ struct _PangoLayoutRun PangoGlyphString *glyphs; }; -PangoLayout * pango_layout_new (PangoContext *context); -void pango_layout_ref (PangoLayout *layout); -void pango_layout_unref (PangoLayout *layout); -void pango_layout_set_width (PangoLayout *layout, - int width); -void pango_layout_set_justify (PangoLayout *layout, - gboolean justify); -void pango_layout_set_first_line_width (PangoLayout *layout, - int width); -void pango_layout_set_attributes (PangoLayout *layout, - PangoAttrList *attrs); -void pango_layout_set_text (PangoLayout *layout, - char *text, - int length); -int pango_layout_get_line_count (PangoLayout *layout); -PangoLayoutLine * pango_layout_get_line (PangoLayout *layout, - int line); -GSList * pango_layout_get_lines (PangoLayout *layout); -void pango_layout_index_to_line_x (PangoLayout *layout, - int index, - gboolean trailing, - int *line, - int *x_pos); +PangoLayout *pango_layout_new (PangoContext *context); +void pango_layout_ref (PangoLayout *layout); +void pango_layout_unref (PangoLayout *layout); + + +void pango_layout_set_attributes (PangoLayout *layout, + PangoAttrList *attrs); +void pango_layout_set_text (PangoLayout *layout, + char *text, + int length); + +void pango_layout_set_width (PangoLayout *layout, + int width); +int pango_layout_get_width (PangoLayout *layout); +void pango_layout_set_indent (PangoLayout *layout, + int indent); +int pango_layout_get_indent (PangoLayout *layout); +void pango_layout_set_justify (PangoLayout *layout, + gboolean justify); +gboolean pango_layout_get_justify (PangoLayout *layout); +void pango_layout_set_alignment (PangoLayout *layout, + PangoAlignment alignment); +PangoAlignment pango_layout_get_alignment (PangoLayout *layout); + + +void pango_layout_index_to_pos (PangoLayout *layout, + int index, + PangoRectangle *pos); +gboolean pango_layout_xy_to_index (PangoLayout *layout, + int x, + int y, + int *index, + gboolean *trailing); +void pango_layout_get_extents (PangoLayout *layout, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect); + +int pango_layout_get_line_count (PangoLayout *layout); +PangoLayoutLine *pango_layout_get_line (PangoLayout *layout, + int line); +GSList * pango_layout_get_lines (PangoLayout *layout); void pango_layout_line_ref (PangoLayoutLine *line); void pango_layout_line_unref (PangoLayoutLine *line); diff --git a/pango/pangox.c b/pango/pangox.c index 423722e5..30a2e3d1 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -2004,19 +2004,18 @@ pango_x_get_unknown_glyph (PangoFont *font) /** * pango_x_render_layout_line: - * @display: the X display - * @d: the drawable on which to draw string - * @gc: the graphics context - * @line: a #PangoLayoutLine - * @glyphs: the glyph string to draw - * @x: the x position of start of string (in pixels) - * @y: the y position of baseline (in pixels) + * @display: the X display + * @drawable: the drawable on which to draw string + * @gc: the graphics context + * @line: a #PangoLayoutLine + * @x: the x position of start of string (in pixels) + * @y: the y position of baseline (in pixels) * * Render a #PangoLayoutLine onto an X drawable */ void pango_x_render_layout_line (Display *display, - Drawable d, + Drawable drawable, GC gc, PangoLayoutLine *line, int x, @@ -2035,7 +2034,7 @@ pango_x_render_layout_line (Display *display, PangoLayoutRun *run = tmp_list->data; tmp_list = tmp_list->next; - pango_x_render (display, d, gc, run->item->analysis.font, run->glyphs, + pango_x_render (display, drawable, gc, run->item->analysis.font, run->glyphs, x + x_off / 1000, y); if (tmp_list) @@ -2046,3 +2045,84 @@ pango_x_render_layout_line (Display *display, } } } + +/** + * pango_x_render_layout: + * @display: the X display + * @drawable: the drawable on which to draw string + * @gc: the graphics context + * @layout: a #PangoLayout + * @x: the X position of the left of the layout (in pixels) + * @y: the Y position of the top of the layout (in pixels) + * + * Render a #PangoLayoutLine onto an X drawable + */ +void +pango_x_render_layout (Display *display, + Drawable drawable, + GC gc, + PangoLayout *layout, + int x, + int y) +{ + PangoRectangle logical_rect; + GSList *tmp_list; + PangoAlignment align; + int indent; + int width; + int y_offset = 0; + + gboolean first = FALSE; + + g_return_if_fail (display != NULL); + g_return_if_fail (layout != NULL); + + indent = pango_layout_get_indent (layout); + width = pango_layout_get_width (layout); + align = pango_layout_get_alignment (layout); + + tmp_list = pango_layout_get_lines (layout); + while (tmp_list) + { + PangoLayoutLine *line = tmp_list->data; + int x_offset; + + pango_layout_line_get_extents (line, NULL, &logical_rect); + + if (width != 1 && align == PANGO_ALIGN_RIGHT) + x_offset = width - logical_rect.width; + else if (width != 1 && align == PANGO_ALIGN_CENTER) + x_offset = (width - logical_rect.width) / 2; + else + x_offset = 0; + + if (first) + { + if (indent > 0) + { + if (align == PANGO_ALIGN_LEFT) + x_offset += indent; + else + x_offset -= indent; + } + + first = FALSE; + } + else + { + if (indent < 0) + { + if (align == PANGO_ALIGN_LEFT) + x_offset -= indent; + else + x_offset += indent; + } + } + + pango_x_render_layout_line (display, drawable, gc, + line, x + x_offset / 1000, y + y_offset / 1000); + + y_offset += logical_rect.height; + tmp_list = tmp_list->next; + } +} diff --git a/pango/pangox.h b/pango/pangox.h index 2e92347d..ad312f2c 100644 --- a/pango/pangox.h +++ b/pango/pangox.h @@ -46,11 +46,17 @@ void pango_x_render (Display *display, gint x, gint y); void pango_x_render_layout_line (Display *display, - Drawable d, + Drawable drawable, GC gc, PangoLayoutLine *line, int x, int y); +void pango_x_render_layout (Display *display, + Drawable drawable, + GC gc, + PangoLayout *layout, + int x, + int y); /* API for rendering modules */ |