]> git.donarmstrong.com Git - xournal.git/commitdiff
Release 0.4
authorauroux <auroux>
Wed, 15 Aug 2007 21:26:51 +0000 (21:26 +0000)
committerauroux <auroux>
Wed, 15 Aug 2007 21:26:51 +0000 (21:26 +0000)
22 files changed:
ChangeLog
NEWS
README
configure.in
html-doc/manual.html
pixmaps/xournal.svg [new file with mode: 0644]
src/TODO
src/main.c
src/sft.h [new file with mode: 0644]
src/xo-callbacks.c
src/xo-callbacks.h
src/xo-file.c
src/xo-interface.c
src/xo-interface.h
src/xo-misc.c
src/xo-misc.h
src/xo-paint.c
src/xo-paint.h
src/xo-print.c
src/xo-print.h
src/xournal.h
xournal.glade

index 2a215d13b6b8c9b7c7d7132ce7a42eaf0806c699..641b1e0756cd15b509ce8f1c536ba36a752ac282 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Version 0.4 (Aug 15, 2007):
+  - text tool (handles most TrueType and Type1 fonts)
+  - font selection dialog and button
+  - keyboard mappings (arrow keys)
+  - menu mnemonics and shortcuts (suggestions by Jean-Baptiste Rouquier)
+  - more responsive hand tool
+  - bugfix for GTK+ 2.11 XInput behavior (thanks to Robert Gerlach)
+  - various minor bugfixes and enhancements
+
 Version 0.3.3 (Jan 31, 2007):
   - bugfix: upon loading a new file, zoom is set to default startup zoom
   - config option to allow input from a mouse or other core pointer device
diff --git a/NEWS b/NEWS
index b8e6d5b12715151da91777da5ac5905afdcea0f1..85f413e311e094b70e252d5a22f9a549dfa60f4a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Version 0.3.3 (January 31, 2007)
+Version 0.4 (August 15, 2007)
 
 Installation:  see INSTALL
 User's manual: see html-doc/manual.html
diff --git a/README b/README
index b8e6d5b12715151da91777da5ac5905afdcea0f1..85f413e311e094b70e252d5a22f9a549dfa60f4a 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Version 0.3.3 (January 31, 2007)
+Version 0.4 (August 15, 2007)
 
 Installation:  see INSTALL
 User's manual: see html-doc/manual.html
index 2da33643c7b0276e640e9d66adf35de885e16add..e0b42abccd32eaaf2e39533bdaadb5a4c7ba1b8d 100644 (file)
@@ -1,7 +1,7 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_INIT(configure.in)
-AM_INIT_AUTOMAKE(xournal, 0.3.3)
+AM_INIT_AUTOMAKE(xournal, 0.4)
 AM_CONFIG_HEADER(config.h)
 AM_MAINTAINER_MODE
 
index f748b5cab871de454aa0c65473f274121f9a2624..6c5fad88ff37e26d403499403d038265146c2118 100644 (file)
@@ -24,7 +24,7 @@
   Xournal User's Manual
 </h2>
 <p style="font-size: 0.95em; text-align: center; color: rgb(0,0,0)">
- Version 0.3.3
+ Version 0.4
 </p>
 <hr />
 <p>
@@ -127,6 +127,28 @@ the Tools menu):
   is yellow) and thicknesses. Use the color and thickness toolbar buttons
   to change these settings.
 </p>
+<h3 class="subsub"><img src="pixmaps/text-tool.png"> The text tool</h3>
+<p>
+  To insert a new text item, click at the location where the text is to be
+  inserted on the page, then type it in or paste it using the contextual
+  menu (note: no wrapping is performed). To modify a text item, click inside
+  it. The font and point size can be modified using the "Text Font" command
+  in the Tools menu (or the toolbar button). The color is the same as that
+  currently selected for the pen (and can be modified using the toolbar
+  buttons).
+</p>
+<p>
+  Text items can contain arbitrary Unicode characters, provided that a
+  suitable font is installed on your system. However, languages written
+  in a direction other than left-to-right might not be handled properly.
+  If a journal contains some items in a font that is unavailable on your
+  system, another one will be substituted. (Also, text items will be
+  lost if the document is opened in a version of Xournal prior to 0.4).
+  Finally, note that the printing and PDF export features only accept
+  TrueType and Type 1 scalable fonts (do not use any bitmap fonts), and
+  that the typesetting of the text may be slightly different in the
+  printout.
+</p>
 <h3 class="subsub"><img src="pixmaps/ruler.png"> The ruler</h3>
 <p>
   The ruler is not a tool by itself, but rather a special operating mode
@@ -136,15 +158,17 @@ the Tools menu):
 </p>
 <h3 class="subsub"><img src="pixmaps/recycled.png"> Default tools</h3>
 <p>
-  Each drawing tool (pen, eraser, highlighter) has a default setting
-  (color, thickness, ...) associated to it.
-  The "Default Pen", "Default Eraser", and "Default Highlighter" entries of
+  Each tool (pen, eraser, highlighter, text) has a default setting
+  (color, thickness, ... for the drawing tools, font and size for the
+  text tool) associated to it.
+  The "Default Pen", "Default Eraser", "Default Highlighter", and
+  "Default Text" entries of
   the Tools menu select the appropriate tool and reset its settings to
   the defaults. The toolbar also includes a "Default" button which
-  resets the currently selected drawing tool to its default settings,
+  resets the currently selected tool to its default settings,
   and a "Default Pen" button. <br />
   The "Set As Default" entry of the Tools menu takes the current settings
-  of the currently selected drawing tool and makes them the new default.
+  of the currently selected tool and makes them the new default.
 </p>
 <a name="thicknesses"></a>
 <h3 class="subsub"><img src="pixmaps/thin.png"> <img src="pixmaps/medium.png">
@@ -471,7 +495,8 @@ file is much more compact than those produced via gnome-print, and
 its pages have the same size as in Xournal. Highlighter strokes
 are rendered in a partially transparent manner (note however that
 applications such as xpdf and ghostview do not always handle
-PDF transparency properly).
+PDF transparency properly). Text items are rendered by embedding
+TrueType subsets or Type 1 fonts into the PDF document as appropriate.
 </p>
 <p>
 Xournal also includes a PDF file parser compatible with PDF format
@@ -495,7 +520,7 @@ configuration file include in particular:
 <li>general display preferences: zoom level, window size, ...</li>
 <li>default paper settings (as set by the "Set As Default" command in
 the Journal menu)</li>
-<li>default tool settings for the pen, eraser, and highlighter
+<li>default settings for the pen, eraser, highlighter, and text tools
 (as set by the "Set As Default" command in the Tools menu)</li>
 <li>mappings for buttons 2 and 3</li>
 <li>the various preferences set in the Options menu</li>
@@ -530,6 +555,18 @@ Bug reports and suggestions can also be submitted on Xournal's
 <a name="changelog"></a>
 <h2 class="subtitle">Version history</h2>
 <p>
+Version 0.4 (August 15, 2007):
+<ul>
+ <li>text tool (handles most TrueType and Type1 fonts)</li>
+ <li>font selection dialog and button</li>
+ <li>keyboard mappings (arrow keys)</li>
+ <li>menu mnemonics and shortcuts (suggestions by Jean-Baptiste Rouquier)</li>
+ <li>more responsive hand tool</li>
+ <li>bugfix for GTK+ 2.11 XInput behavior (thanks to Robert Gerlach)</li>
+ <li>various minor bugfixes and enhancements</li>
+</ul>
+</p>
+<p>
 Version 0.3.3 (January 31, 2007):
 <ul>
  <li>bugfix: upon loading a new file, zoom is set to default startup zoom</li>
@@ -627,17 +664,21 @@ Version 0.1 (January 2, 2006): initial release.
 <p>
 Xournal stores its data in gzipped XML-like files. The gzipped data consists
 of a succession of XML tags describing the document. By convention, the
-first few lines contain a header in the following format:
+file header and trailer look like this:
 <pre>
 &lt;?xml version="1.0" standalone="no"?&gt;
+&lt;xournal version="..."&gt;
 &lt;title&gt;Xournal document - see http://math.mit.edu/~auroux/software/xournal/&lt;/title&gt;
-&lt;xournal version="..."/&gt;
+... sequence of pages ...
+&lt;/xournal&gt;
 </pre>
 The &lt;title&gt; and &lt;xournal&gt; tags may only appear within the file
 header (not within the pages of the document). The <i>version</i> attribute of
 the &lt;xournal&gt; tag indicates which version of Xournal was used to
 create the document; it is currently ignored, but may be used in a later
 release if the file format changes in an incompatible manner.
+(Following a suggestion of Matteo Abrate, starting with version 0.4 the
+&lt;xournal&gt; tag is the document's root tag, and encloses all other tags).
 </p>
 <p>
 The rest of the file is a sequence of pages, specified by a
@@ -711,15 +752,15 @@ page of the PDF file.
 After the line specifying the background, the remainder of a &lt;page&gt;
 section is occupied by one or more layer sections
 <pre>&lt;layer&gt; ... &lt;/layer&gt;</pre>
-describing the various strokes within a layer. Every page must
+describing the various items within a layer. Every page must
 contain at least one layer; a layer may be empty. The successive layers
 are listed in their stacking order, from bottom to top.
 </p>
 <p>
-A layer consist of a collection of items, listed in the order in which
+A layer consists of a collection of items, listed in the order in which
 they should be drawn
 (from bottom-most to top-most).
-As of the current version, the only legal contents within a layer are 
+Up to version 0.3.3, the only legal contents within a layer are 
 strokes. The format of a stroke is:
 <pre>&lt;stroke tool="..." color="..." width="..."&gt;
 ... list of coordinates ...
@@ -753,6 +794,25 @@ appropriate (otherwise the eraser tool will not interact properly with the
 stroke). The default precision used by Xournal for the x,y coordinates is
 0.01 unit (1/7200 in).
 </p>
+<p>Starting with version 0.4, layers also contain text items.
+The format of a text item is:
+<pre>&lt;text font="..." size="..." x="..." y="..." color="..."&gt;... text ...&lt;/text&gt;
+</pre>
+The <i>font</i> attribute contains the font name, for example "Serif Bold
+Italic"; if the font is not available, another font will be substituted.
+The <i>size</i> attribute specifies the font size in points. The <i>x</i>
+and <i>y</i> attributes specify the coordinates of the top-left corner
+of the text box in page coordinates (measured in points from the top-left
+corner of the page). Finally, the <i>color</i> attribute contains either
+the name of a standard color or a hexadecimal RGBA value (see above).
+</p>
+<p>
+The contents of the text are encoded in UTF-8, with the characters
+<tt>'&amp;', '&lt;', '&gt;'</tt> replaced by <tt>&amp;amp;, &amp;lt;,
+&amp;gt;</tt>. Whitespace and linefeeds are preserved (in particular,
+no extraneous whitespace should be inserted between the enclosing tags
+and the text itself).
+</p>
 <hr />
 <a name="installation"></a>
 <h2 class="subtitle">Installation issues</h2>
diff --git a/pixmaps/xournal.svg b/pixmaps/xournal.svg
new file mode 100644 (file)
index 0000000..11c3de6
--- /dev/null
@@ -0,0 +1,1177 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   inkscape:export-ydpi="90.000000"
+   inkscape:export-xdpi="90.000000"
+   inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+   width="48px"
+   height="48px"
+   id="svg11300"
+   sodipodi:version="0.32"
+   inkscape:version="0.45"
+   sodipodi:docbase="/home/michele/Documents/xournal icon"
+   sodipodi:docname="xournal.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <defs
+     id="defs3">
+    <linearGradient
+       id="linearGradient2994">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop2996" />
+      <stop
+         style="stop-color:#c9c9c9;stop-opacity:1;"
+         offset="1"
+         id="stop2998" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2984">
+      <stop
+         style="stop-color:#e7e2b8;stop-opacity:1;"
+         offset="0"
+         id="stop2986" />
+      <stop
+         style="stop-color:#e7e2b8;stop-opacity:0;"
+         offset="1"
+         id="stop2988" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2974">
+      <stop
+         style="stop-color:#c1c1c1;stop-opacity:1;"
+         offset="0"
+         id="stop2976" />
+      <stop
+         style="stop-color:#acacac;stop-opacity:1;"
+         offset="1"
+         id="stop2978" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2966">
+      <stop
+         style="stop-color:#ffd1d1;stop-opacity:1;"
+         offset="0"
+         id="stop2968" />
+      <stop
+         id="stop3006"
+         offset="0.5"
+         style="stop-color:#ff1d1d;stop-opacity:1;" />
+      <stop
+         style="stop-color:#6f0000;stop-opacity:1;"
+         offset="1"
+         id="stop2970" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2919">
+      <stop
+         style="stop-color:#a3a4a0;stop-opacity:1;"
+         offset="0"
+         id="stop2921" />
+      <stop
+         style="stop-color:#888a85;stop-opacity:1;"
+         offset="1"
+         id="stop2923" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2873">
+      <stop
+         style="stop-color:#939393;stop-opacity:1;"
+         offset="0"
+         id="stop2875" />
+      <stop
+         style="stop-color:#424242;stop-opacity:1;"
+         offset="1"
+         id="stop2877" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2865">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop2867" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop2869" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2855">
+      <stop
+         style="stop-color:#dfdfdf;stop-opacity:1;"
+         offset="0"
+         id="stop2857" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="1"
+         id="stop2859" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2855"
+       id="linearGradient2861"
+       x1="21.043484"
+       y1="42.83337"
+       x2="14.283642"
+       y2="6.8333683"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.137871,0.000000,0.000000,1.000000,-2.660884,0.000000)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2865"
+       id="radialGradient2871"
+       cx="23.5625"
+       cy="40.4375"
+       fx="23.5625"
+       fy="40.4375"
+       r="19.5625"
+       gradientTransform="matrix(1.000000,0.000000,0.000000,0.348243,0.000000,26.35543)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2873"
+       id="linearGradient2879"
+       x1="26.612417"
+       y1="28.083368"
+       x2="26.228401"
+       y2="42.83337"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2919"
+       id="linearGradient2925"
+       x1="6"
+       y1="7.5624999"
+       x2="40.984375"
+       y2="7.5624999"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       y2="68.224884"
+       x2="28.244684"
+       y1="60.445503"
+       x1="28.244684"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient9972"
+       xlink:href="#linearGradient9910"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       y2="68.224884"
+       x2="28.244684"
+       y1="60.445503"
+       x1="28.244684"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient9968"
+       xlink:href="#linearGradient9920"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       y2="68.224884"
+       x2="28.244684"
+       y1="60.445503"
+       x1="28.244684"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient9965"
+       xlink:href="#linearGradient9910"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       y2="62.827091"
+       x2="38.061356"
+       y1="62.401989"
+       x1="55.876038"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient9961"
+       xlink:href="#linearGradient9952"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientUnits="userSpaceOnUse"
+       y2="44.110912"
+       x2="20.682873"
+       y1="27.140348"
+       x1="20.064156"
+       id="linearGradient6401"
+       xlink:href="#linearGradient6395"
+       inkscape:collect="always" />
+    <radialGradient
+       r="14.875"
+       fy="37.75"
+       fx="23.25"
+       cy="37.75"
+       cx="23.25"
+       gradientTransform="matrix(1,0,0,0.420168,8.187895e-16,21.88866)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient6353"
+       xlink:href="#linearGradient5048"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="30.703125"
+       x2="25.514589"
+       y1="31.046875"
+       x1="25.71875"
+       gradientTransform="matrix(5.259571e-3,0.999987,0.999987,-5.259571e-3,48.6929,-14.14491)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6349"
+       xlink:href="#linearGradient2994"
+       inkscape:collect="always" />
+    <radialGradient
+       r="3.2408545"
+       fy="27.640751"
+       fx="29.053354"
+       cy="27.640751"
+       cx="29.053354"
+       gradientTransform="matrix(1.53767e-2,2.923527,2.029691,-1.067544e-2,20.39098,-69.72665)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient6347"
+       xlink:href="#linearGradient2984"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="22.625"
+       x2="47.6875"
+       y1="19.8125"
+       x1="46"
+       gradientTransform="matrix(5.259571e-3,0.999987,0.999987,-5.259571e-3,42.99552,-2.496241)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6345"
+       xlink:href="#linearGradient2974"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="22.250591"
+       x2="50.988335"
+       y1="17.376184"
+       x1="48.90625"
+       gradientTransform="matrix(5.259571e-3,0.999987,0.999987,-5.259571e-3,42.9955,-2.496241)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6343"
+       xlink:href="#linearGradient2966"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientUnits="userSpaceOnUse"
+       y2="14.1875"
+       x2="37.625"
+       y1="14.1875"
+       x1="11.75"
+       id="linearGradient5074"
+       xlink:href="#linearGradient5068"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="translate(0,5.625)"
+       gradientUnits="userSpaceOnUse"
+       y2="19.0846"
+       x2="15.625"
+       y1="19.4596"
+       x1="30.875"
+       id="linearGradient5064"
+       xlink:href="#linearGradient5058"
+       inkscape:collect="always" />
+    <radialGradient
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.420168,0,21.88866)"
+       r="14.875"
+       fy="37.75"
+       fx="23.25"
+       cy="37.75"
+       cx="23.25"
+       id="radialGradient5054"
+       xlink:href="#linearGradient5048"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="translate(0,5.625)"
+       gradientUnits="userSpaceOnUse"
+       y2="26.0846"
+       x2="34.250416"
+       y1="26.0846"
+       x1="15.375"
+       id="linearGradient5042"
+       xlink:href="#linearGradient5036"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5036">
+      <stop
+         id="stop5038"
+         offset="0"
+         style="stop-color:#f5f5f5;stop-opacity:0.09;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.89999998;"
+         offset="0.2631579"
+         id="stop5044" />
+      <stop
+         id="stop5088"
+         offset="0.74792242"
+         style="stop-color:#c7c7c7;stop-opacity:0.46000001;" />
+      <stop
+         id="stop5040"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0.78039217;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5048"
+       inkscape:collect="always">
+      <stop
+         id="stop5050"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop5052"
+         offset="1"
+         style="stop-color:#000000;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5058">
+      <stop
+         id="stop5060"
+         offset="0"
+         style="stop-color:#959791;stop-opacity:1;" />
+      <stop
+         style="stop-color:#f8f8f8;stop-opacity:1;"
+         offset="0.5"
+         id="stop5066" />
+      <stop
+         id="stop5062"
+         offset="1"
+         style="stop-color:#8c8c8c;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5068">
+      <stop
+         id="stop5070"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.69;"
+         offset="0.32894737"
+         id="stop5078" />
+      <stop
+         style="stop-color:#c2c2c2;stop-opacity:0.34;"
+         offset="0.65789473"
+         id="stop5076" />
+      <stop
+         id="stop5072"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient1675">
+      <stop
+         id="stop1677"
+         offset="0"
+         style="stop-color:#ffd1d1;stop-opacity:1;" />
+      <stop
+         style="stop-color:#ff1d1d;stop-opacity:1;"
+         offset="0.5"
+         id="stop1679" />
+      <stop
+         id="stop1681"
+         offset="1"
+         style="stop-color:#6f0000;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient1669">
+      <stop
+         id="stop1671"
+         offset="0"
+         style="stop-color:#c1c1c1;stop-opacity:1;" />
+      <stop
+         id="stop1673"
+         offset="1"
+         style="stop-color:#acacac;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient1657">
+      <stop
+         id="stop1659"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop1661"
+         offset="1"
+         style="stop-color:#c9c9c9;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6395"
+       inkscape:collect="always">
+      <stop
+         id="stop6397"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop6399"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient9910">
+      <stop
+         id="stop9912"
+         offset="0"
+         style="stop-color:#729fcf;stop-opacity:1;" />
+      <stop
+         style="stop-color:#a5bfda;stop-opacity:1;"
+         offset="0.31578946"
+         id="stop9918" />
+      <stop
+         id="stop9914"
+         offset="1"
+         style="stop-color:#376ca4;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient9920">
+      <stop
+         style="stop-color:#5b90c8;stop-opacity:1;"
+         offset="0"
+         id="stop9922" />
+      <stop
+         id="stop9924"
+         offset="0.31578946"
+         style="stop-color:#8fb0d1;stop-opacity:1;" />
+      <stop
+         style="stop-color:#34679d;stop-opacity:1;"
+         offset="1"
+         id="stop9926" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient9952"
+       inkscape:collect="always">
+      <stop
+         id="stop9954"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop9956"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       y2="68.224884"
+       x2="28.244684"
+       y1="60.445503"
+       x1="28.244684"
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient1384"
+       xlink:href="#linearGradient9910"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="68.224884"
+       x2="28.244684"
+       y1="60.445503"
+       x1="28.244684"
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient1381"
+       xlink:href="#linearGradient9920"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="68.224884"
+       x2="28.244684"
+       y1="60.445503"
+       x1="28.244684"
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient1378"
+       xlink:href="#linearGradient9910"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="62.827091"
+       x2="38.061356"
+       y1="62.401989"
+       x1="55.876038"
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient1375"
+       xlink:href="#linearGradient9952"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       y2="68.224884"
+       x2="28.244684"
+       y1="60.445503"
+       x1="28.244684"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2065"
+       xlink:href="#linearGradient9910"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       y2="68.224884"
+       x2="28.244684"
+       y1="60.445503"
+       x1="28.244684"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2063"
+       xlink:href="#linearGradient9920"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       y2="68.224884"
+       x2="28.244684"
+       y1="60.445503"
+       x1="28.244684"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2061"
+       xlink:href="#linearGradient9910"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       y2="62.827091"
+       x2="38.061356"
+       y1="62.401989"
+       x1="55.876038"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2059"
+       xlink:href="#linearGradient9952"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientUnits="userSpaceOnUse"
+       y2="44.110912"
+       x2="20.682873"
+       y1="27.140348"
+       x1="20.064156"
+       id="linearGradient2057"
+       xlink:href="#linearGradient6395"
+       inkscape:collect="always" />
+    <radialGradient
+       r="14.875"
+       fy="37.75"
+       fx="23.25"
+       cy="37.75"
+       cx="23.25"
+       gradientTransform="matrix(1,0,0,0.420168,8.187895e-16,21.88866)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient2055"
+       xlink:href="#linearGradient5048"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="30.703125"
+       x2="25.514589"
+       y1="31.046875"
+       x1="25.71875"
+       gradientTransform="matrix(5.259571e-3,0.999987,0.999987,-5.259571e-3,48.6929,-14.14491)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2053"
+       xlink:href="#linearGradient2994"
+       inkscape:collect="always" />
+    <radialGradient
+       r="3.2408545"
+       fy="27.640751"
+       fx="29.053354"
+       cy="27.640751"
+       cx="29.053354"
+       gradientTransform="matrix(1.53767e-2,2.923527,2.029691,-1.067544e-2,20.39098,-69.72665)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient2051"
+       xlink:href="#linearGradient2984"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="22.625"
+       x2="47.6875"
+       y1="19.8125"
+       x1="46"
+       gradientTransform="matrix(5.259571e-3,0.999987,0.999987,-5.259571e-3,42.99552,-2.496241)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2049"
+       xlink:href="#linearGradient2974"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="22.250591"
+       x2="50.988335"
+       y1="17.376184"
+       x1="48.90625"
+       gradientTransform="matrix(5.259571e-3,0.999987,0.999987,-5.259571e-3,42.9955,-2.496241)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2047"
+       xlink:href="#linearGradient2966"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientUnits="userSpaceOnUse"
+       y2="14.1875"
+       x2="37.625"
+       y1="14.1875"
+       x1="11.75"
+       id="linearGradient2045"
+       xlink:href="#linearGradient5068"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="translate(0,5.625)"
+       gradientUnits="userSpaceOnUse"
+       y2="19.0846"
+       x2="15.625"
+       y1="19.4596"
+       x1="30.875"
+       id="linearGradient2043"
+       xlink:href="#linearGradient5058"
+       inkscape:collect="always" />
+    <radialGradient
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.420168,0,21.88866)"
+       r="14.875"
+       fy="37.75"
+       fx="23.25"
+       cy="37.75"
+       cx="23.25"
+       id="radialGradient2041"
+       xlink:href="#linearGradient5048"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="translate(0,5.625)"
+       gradientUnits="userSpaceOnUse"
+       y2="26.0846"
+       x2="34.250416"
+       y1="26.0846"
+       x1="15.375"
+       id="linearGradient2039"
+       xlink:href="#linearGradient5036"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient2029">
+      <stop
+         id="stop2031"
+         offset="0"
+         style="stop-color:#f5f5f5;stop-opacity:0.09;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.89999998;"
+         offset="0.2631579"
+         id="stop2033" />
+      <stop
+         id="stop2035"
+         offset="0.74792242"
+         style="stop-color:#c7c7c7;stop-opacity:0.46000001;" />
+      <stop
+         id="stop2037"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0.78039217;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2015">
+      <stop
+         id="stop2017"
+         offset="0"
+         style="stop-color:#959791;stop-opacity:1;" />
+      <stop
+         style="stop-color:#f8f8f8;stop-opacity:1;"
+         offset="0.5"
+         id="stop2019" />
+      <stop
+         id="stop2021"
+         offset="1"
+         style="stop-color:#8c8c8c;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2005">
+      <stop
+         id="stop2007"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.69;"
+         offset="0.32894737"
+         id="stop2009" />
+      <stop
+         style="stop-color:#c2c2c2;stop-opacity:0.34;"
+         offset="0.65789473"
+         id="stop2011" />
+      <stop
+         id="stop2013"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient1997">
+      <stop
+         id="stop1999"
+         offset="0"
+         style="stop-color:#ffd1d1;stop-opacity:1;" />
+      <stop
+         style="stop-color:#ff1d1d;stop-opacity:1;"
+         offset="0.5"
+         id="stop2001" />
+      <stop
+         id="stop2003"
+         offset="1"
+         style="stop-color:#6f0000;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient1991">
+      <stop
+         id="stop1993"
+         offset="0"
+         style="stop-color:#c1c1c1;stop-opacity:1;" />
+      <stop
+         id="stop1995"
+         offset="1"
+         style="stop-color:#acacac;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient1979">
+      <stop
+         id="stop1981"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop1983"
+         offset="1"
+         style="stop-color:#c9c9c9;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient1965">
+      <stop
+         id="stop1967"
+         offset="0"
+         style="stop-color:#729fcf;stop-opacity:1;" />
+      <stop
+         style="stop-color:#a5bfda;stop-opacity:1;"
+         offset="0.31578946"
+         id="stop1969" />
+      <stop
+         id="stop1971"
+         offset="1"
+         style="stop-color:#376ca4;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient1957">
+      <stop
+         style="stop-color:#5b90c8;stop-opacity:1;"
+         offset="0"
+         id="stop1959" />
+      <stop
+         id="stop1961"
+         offset="0.31578946"
+         style="stop-color:#8fb0d1;stop-opacity:1;" />
+      <stop
+         style="stop-color:#34679d;stop-opacity:1;"
+         offset="1"
+         id="stop1963" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5048"
+       id="radialGradient2083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.420168,2.131628e-14,21.88866)"
+       cx="23.25"
+       cy="37.75"
+       fx="23.25"
+       fy="37.75"
+       r="14.875" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5048"
+       id="radialGradient1499"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.420168,2.842171e-14,21.88866)"
+       cx="23.25"
+       cy="37.75"
+       fx="23.25"
+       fy="37.75"
+       r="14.875" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9910"
+       id="linearGradient1501"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       x1="28.244684"
+       y1="60.445503"
+       x2="28.244684"
+       y2="68.224884" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9920"
+       id="linearGradient1503"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       x1="28.244684"
+       y1="60.445503"
+       x2="28.244684"
+       y2="68.224884" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9910"
+       id="linearGradient1505"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       x1="28.244684"
+       y1="60.445503"
+       x2="28.244684"
+       y2="68.224884" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9952"
+       id="linearGradient1507"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.493304,-0.716654,-0.716654,-0.493304,53.68973,79.4192)"
+       x1="55.876038"
+       y1="62.401989"
+       x2="38.061356"
+       y2="62.827091" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9952"
+       id="linearGradient1510"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.345313,-0.501658,-0.501658,-0.345313,87.52497,58.69517)"
+       x1="55.876038"
+       y1="62.401989"
+       x2="38.061356"
+       y2="62.827091" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9910"
+       id="linearGradient1513"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.345313,-0.501658,-0.501658,-0.345313,87.52497,58.69517)"
+       x1="28.244684"
+       y1="60.445503"
+       x2="28.244684"
+       y2="68.224884" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9920"
+       id="linearGradient1516"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.345313,-0.501658,-0.501658,-0.345313,87.52497,58.69517)"
+       x1="28.244684"
+       y1="60.445503"
+       x2="28.244684"
+       y2="68.224884" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9910"
+       id="linearGradient1519"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.345313,-0.501658,-0.501658,-0.345313,87.52497,58.69517)"
+       x1="28.244684"
+       y1="60.445503"
+       x2="28.244684"
+       y2="68.224884" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5048"
+       id="radialGradient1526"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.420168,2.790129e-14,21.88866)"
+       cx="23.25"
+       cy="37.75"
+       fx="23.25"
+       fy="37.75"
+       r="14.875" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9910"
+       id="linearGradient1538"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.345313,-0.501658,-0.501658,-0.345313,87.52497,58.69517)"
+       x1="28.244684"
+       y1="60.445503"
+       x2="28.244684"
+       y2="68.224884" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9920"
+       id="linearGradient1540"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.345313,-0.501658,-0.501658,-0.345313,87.52497,58.69517)"
+       x1="28.244684"
+       y1="60.445503"
+       x2="28.244684"
+       y2="68.224884" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9910"
+       id="linearGradient1542"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.345313,-0.501658,-0.501658,-0.345313,87.52497,58.69517)"
+       x1="28.244684"
+       y1="60.445503"
+       x2="28.244684"
+       y2="68.224884" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9952"
+       id="linearGradient1544"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.345313,-0.501658,-0.501658,-0.345313,87.52497,58.69517)"
+       x1="55.876038"
+       y1="62.401989"
+       x2="38.061356"
+       y2="62.827091" />
+  </defs>
+  <sodipodi:namedview
+     stroke="#c4a000"
+     fill="#edd400"
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="0.25490196"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.104167"
+     inkscape:cx="34.965108"
+     inkscape:cy="24.000001"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:showpageshadow="false"
+     inkscape:window-width="1024"
+     inkscape:window-height="721"
+     inkscape:window-x="0"
+     inkscape:window-y="46" />
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Jakub Steiner</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <dc:source>http://jimmac.musichall.cz</dc:source>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+        <dc:title>Text Editor</dc:title>
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Reproduction" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Distribution" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Notice" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Attribution" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/ShareAlike" />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer">
+    <g
+       id="g1390">
+      <path
+         transform="matrix(1.000000,0.000000,0.000000,0.651376,0.000000,15.34748)"
+         d="M 43.125 40.4375 A 19.5625 6.8125 0 1 1  4,40.4375 A 19.5625 6.8125 0 1 1  43.125 40.4375 z"
+         sodipodi:ry="6.8125"
+         sodipodi:rx="19.5625"
+         sodipodi:cy="40.4375"
+         sodipodi:cx="23.5625"
+         id="path2863"
+         style="opacity:0.62573099;color:#000000;fill:url(#radialGradient2871);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         sodipodi:type="arc" />
+      <path
+         sodipodi:nodetypes="ccccccccccc"
+         id="rect1975"
+         d="M 7.1638699,4.5063726 L 39.813122,4.5063726 C 40.575699,4.5063726 41.189615,5.0388241 41.189615,5.7002099 C 41.189615,5.7002099 43.590945,39.868907 43.590945,39.868907 C 43.590945,39.868907 43.603403,42.216529 43.603403,42.216529 C 43.603403,42.877915 42.989488,43.410366 42.226911,43.410366 L 4.750081,43.410366 C 3.9875042,43.410366 3.3735887,42.877915 3.3735887,42.216529 L 3.3624173,40.049613 L 5.7873775,5.7002099 C 5.7873775,5.0388241 6.4012931,4.5063726 7.1638699,4.5063726 z "
+         style="color:#000000;fill:url(#linearGradient2861);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2879);stroke-width:0.99999982;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <rect
+         ry="0.67937863"
+         rx="0.67937863"
+         y="39.868271"
+         x="3.9770372"
+         height="3.0714951"
+         width="39.048077"
+         id="rect2851"
+         style="opacity:1;color:#000000;fill:#a4a4a4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <path
+         sodipodi:nodetypes="ccccccc"
+         id="path2853"
+         d="M 3.9267507,40.442796 C 3.9267507,40.442796 4.0776125,39.912466 4.6307727,39.868272 L 42.195375,39.868272 C 42.949684,39.868272 42.999971,40.619573 42.999971,40.619573 C 42.999971,40.619573 43.02357,39 41.7161,39 L 5.3042159,39 C 4.2984702,39.088388 3.9267507,39.779883 3.9267507,40.442796 z "
+         style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <path
+         sodipodi:nodetypes="ccccccccc"
+         id="path2915"
+         d="M 6.25,5.7343749 L 6,10.125 C 6,10.125 6.3125,8.9999999 7,8.9999999 L 40.125,8.9999999 C 40.828125,8.9843749 40.859375,9.3124999 40.984375,9.8281249 C 40.984375,9.8281249 40.734375,5.9531249 40.734375,5.9531249 C 40.703125,5.4062499 40.515625,4.9999999 39.953125,4.9999999 L 7.0625,4.9999999 C 6.609375,4.9999999 6.296875,5.3437499 6.25,5.7343749 z "
+         style="opacity:1;color:#000000;fill:url(#linearGradient2925);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <path
+         style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:0.43859649"
+         d="M 7.8126474,5.5404503 L 38.944983,5.5404503 C 39.66702,5.5404503 40.2483,5.3883462 40.2483,6.014572 C 40.2483,6.014572 42.521973,39.023077 42.521973,39.023077 C 42.521973,39.023077 42.622156,41.732033 42.622156,41.732033 C 42.622156,42.358259 42.48282,42.376269 41.760782,42.376269 L 4.8620444,42.376269 C 4.4493662,42.376269 4.4426114,42.269871 4.4426114,41.864615 L 4.4320338,39.194177 L 6.7280807,6.045822 C 6.7280807,5.4195962 7.09061,5.5404503 7.8126474,5.5404503 z "
+         id="path2917"
+         sodipodi:nodetypes="ccccccccccc" />
+      <g
+         id="g2950">
+        <rect
+           style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+           id="rect2899"
+           width="2"
+           height="5"
+           x="8.5"
+           y="2.5"
+           rx="1"
+           ry="1" />
+        <rect
+           ry="1"
+           rx="1"
+           y="2.5"
+           x="12.5"
+           height="5"
+           width="2"
+           id="rect2901"
+           style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+        <rect
+           style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+           id="rect2903"
+           width="2"
+           height="5"
+           x="16.5"
+           y="2.5"
+           rx="1"
+           ry="1" />
+        <rect
+           ry="1"
+           rx="1"
+           y="2.5"
+           x="20.5"
+           height="5"
+           width="2"
+           id="rect2905"
+           style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+        <rect
+           style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+           id="rect2907"
+           width="2"
+           height="5"
+           x="24.5"
+           y="2.5"
+           rx="1"
+           ry="1" />
+        <rect
+           ry="1"
+           rx="1"
+           y="2.5"
+           x="28.5"
+           height="5"
+           width="2"
+           id="rect2909"
+           style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+        <rect
+           style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+           id="rect2911"
+           width="2"
+           height="5"
+           x="32.5"
+           y="2.5"
+           rx="1"
+           ry="1" />
+        <rect
+           ry="1"
+           rx="1"
+           y="2.5"
+           x="36.5"
+           height="5"
+           width="2"
+           id="rect2913"
+           style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      </g>
+    </g>
+    <path
+       transform="matrix(1.114155,5.614352e-2,-5.752201e-2,0.894643,0,0)"
+       style="font-size:62.90097427px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Andy MT"
+       d="M 23.095211,22.673472 C 23.177098,22.775867 23.392092,23.001098 23.740192,23.349166 C 28.65431,28.775205 31.039712,31.836301 30.896406,32.532462 C 30.794006,33.044359 30.445921,33.494821 29.852152,33.88385 C 29.258339,34.252416 28.715736,34.436697 28.224344,34.436691 C 27.835288,34.436697 25.869634,32.143434 22.327377,27.556897 C 21.610718,26.594558 21.190969,26.051956 21.068129,25.929088 C 20.617654,26.58432 19.962436,27.915232 19.102474,29.921826 C 18.262965,31.907965 17.689649,33.474345 17.382525,34.620971 C 17.996782,34.109088 18.508671,33.853143 18.918194,33.853137 C 19.122938,33.853143 19.266267,33.996472 19.348181,34.283124 C 19.450547,34.549312 19.471022,34.846208 19.409607,35.173812 C 19.348169,35.399048 18.877231,35.84951 17.996793,36.5252 C 17.36204,36.996141 16.962767,37.32375 16.798971,37.508028 C 16.287073,37.978968 15.949227,38.61371 15.78543,39.412256 C 15.560191,40.579364 14.864022,41.162917 13.696921,41.162918 C 13.082649,41.162917 12.693613,40.937686 12.529813,40.487224 C 12.366004,40.036761 12.38648,39.320117 12.59124,38.337288 C 12.980271,36.371637 15.089253,31.529167 18.918194,23.809866 C 18.877231,23.482273 18.211776,22.325404 16.921825,20.339256 C 15.631856,18.353146 14.618315,16.981284 13.881202,16.223665 C 13.082649,15.404666 12.734564,14.759686 12.836947,14.288723 C 13.062173,13.121642 13.932384,12.538088 15.447583,12.538061 C 16.184696,12.538088 17.587271,14.258035 19.655314,17.697906 C 20.535751,19.110742 21.109067,19.970715 21.375263,20.277829 C 21.78476,19.76596 22.358076,18.834322 23.095211,17.482913 C 23.832316,16.111073 24.333967,15.005393 24.600166,14.165869 C 24.866332,13.387824 25.316794,12.753082 25.951554,12.26164 C 26.586279,11.770255 27.200545,11.524548 27.794356,11.52452 C 28.715736,11.524548 29.074059,12.005724 28.869324,12.968048 C 28.644072,14.135182 27.118643,16.766291 24.293033,20.861383 C 23.555896,21.926131 23.156623,22.53016 23.095211,22.673472"
+       id="text1485" />
+    <path
+       sodipodi:type="arc"
+       style="opacity:0.31868131;color:#000000;fill:url(#radialGradient1526);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       id="path5046"
+       sodipodi:cx="23.25"
+       sodipodi:cy="37.75"
+       sodipodi:rx="14.375"
+       sodipodi:ry="5.75"
+       d="M 37.625 37.75 A 14.375 5.75 0 1 1  8.875,37.75 A 14.375 5.75 0 1 1  37.625 37.75 z"
+       inkscape:r_cx="true"
+       inkscape:r_cy="true"
+       transform="matrix(-0.7,0,0,0.7,46.3375,9.6)" />
+    <g
+       id="g1528"
+       transform="matrix(0.839608,0.133267,-0.134811,0.829988,-26.05355,-2.158778)">
+      <path
+         inkscape:r_cy="true"
+         inkscape:r_cx="true"
+         sodipodi:nodetypes="cszsc"
+         id="path9903"
+         d="M 64.323851,23.753654 C 63.706163,23.328472 61.957281,24.862952 60.381466,27.152239 C 58.80565,29.441527 58.478283,31.954496 58.614374,32.048174 C 58.766049,32.152578 60.980944,30.938876 62.55676,28.649588 C 64.132575,26.3603 64.94154,24.178835 64.323851,23.753654 z "
+         style="color:#000000;fill:#e7e7e7;fill-opacity:1;fill-rule:evenodd;stroke:#7d7d7d;stroke-width:0.69999969;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <g
+         inkscape:r_cy="true"
+         inkscape:r_cx="true"
+         transform="matrix(-0.55721,5.78064e-2,5.78064e-2,0.55721,79.96601,2.590748)"
+         id="g9975">
+        <path
+           sodipodi:type="arc"
+           style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#3465a4;stroke-width:1.25350261;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+           id="path9905"
+           sodipodi:cx="40.1875"
+           sodipodi:cy="62"
+           sodipodi:rx="13.0625"
+           sodipodi:ry="5.5"
+           d="M 32.085889,57.685642 A 13.0625,5.5 0 0 1 52.946432,60.821161"
+           inkscape:r_cx="true"
+           inkscape:r_cy="true"
+           sodipodi:start="4.0433671"
+           sodipodi:end="6.067175"
+           sodipodi:open="true"
+           transform="matrix(-0.56251,-0.817194,0.825069,-0.567931,-15.22056,83.88674)" />
+        <path
+           sodipodi:type="arc"
+           style="color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:evenodd;stroke:#3465a4;stroke-width:1.25350261;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+           id="path9907"
+           sodipodi:cx="33.5"
+           sodipodi:cy="54.9375"
+           sodipodi:rx="3"
+           sodipodi:ry="1.5625"
+           d="M 36.364517,54.473244 A 3,1.5625 0 0 1 30.693831,55.490029 L 33.5,54.9375 z"
+           inkscape:r_cx="true"
+           inkscape:r_cy="true"
+           sodipodi:start="5.9815064"
+           sodipodi:end="9.0633414"
+           transform="matrix(-0.56251,-0.817194,0.825069,-0.567931,-14.28556,81.45324)" />
+      </g>
+      <path
+         inkscape:r_cy="true"
+         inkscape:r_cx="true"
+         id="path9898"
+         d="M 68.220855,22.03384 C 66.161588,24.942137 64.137874,27.460945 62.467865,29.270908 L 59.760605,27.407384 C 60.993535,24.922104 62.913702,21.706016 65.241996,18.323557 C 69.444736,12.21797 73.612295,7.5665296 75.260752,7.0147343 C 75.311342,6.9987019 75.379183,6.9775974 75.424823,6.9695952 C 75.456909,6.9647079 75.504446,6.9663697 75.533931,6.9656604 C 75.580264,6.9658747 75.63967,6.975441 75.679136,6.9865735 C 75.688784,6.989702 75.718329,6.9897217 75.727538,6.9935444 C 75.736526,6.997714 75.755092,7.0135223 75.763635,7.0183914 C 75.767794,7.0210008 75.777636,7.0280287 75.781683,7.0308147 C 75.785731,7.0336007 75.795809,7.0402845 75.799732,7.0432381 C 75.807329,7.0494797 75.828724,7.0611783 75.835828,7.068085 C 75.842686,7.075322 75.853253,7.1029128 75.85962,7.1108081 C 75.884109,7.1436991 75.914254,7.1957743 75.930996,7.2389772 C 75.940861,7.2667725 75.959385,7.3105836 75.966275,7.3423002 C 75.975094,7.3877889 75.979602,7.4586944 75.982687,7.511674 C 76.055791,9.2484938 73.198804,14.802057 68.996063,20.907645 C 68.73456,21.287548 68.481406,21.665863 68.220855,22.03384 z "
+         style="color:#000000;fill:url(#linearGradient1538);fill-opacity:1;fill-rule:evenodd;stroke:#3465a4;stroke-width:0.69999981;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <path
+         inkscape:r_cy="true"
+         inkscape:r_cx="true"
+         id="path9893"
+         d="M 71.416857,17.699951 C 70.893924,18.433249 70.352189,19.137828 69.837722,19.800844 L 66.047558,17.19191 C 66.667225,16.171651 67.355385,15.098728 68.098369,14.019347 C 71.644431,8.8677579 75.303395,5.042076 76.878437,4.7032625 C 76.892273,4.7005267 76.925638,4.6945386 76.939144,4.6923573 C 76.952484,4.6904538 76.986846,4.6827969 76.999851,4.6814522 C 77.031942,4.67879 77.079004,4.6766455 77.108959,4.6775174 C 77.120769,4.6781515 77.145901,4.6832822 77.157361,4.6844884 C 77.191215,4.6889688 77.241564,4.701155 77.272212,4.7108538 C 77.282248,4.7143793 77.310943,4.7137117 77.320615,4.7178248 C 77.334846,4.7244363 77.361358,4.74715 77.37476,4.7550951 C 77.379134,4.7578925 77.388527,4.7645722 77.392808,4.7675187 C 77.397089,4.7704652 77.406682,4.776855 77.410856,4.779942 C 77.423062,4.7896242 77.453744,4.8062785 77.465001,4.8172126 C 77.472296,4.8247781 77.481917,4.85182 77.488793,4.8599357 C 77.508796,4.8851017 77.538154,4.9277816 77.554426,4.9578055 C 77.559644,4.9680796 77.573409,4.9897239 77.578218,5.0005286 C 77.589727,5.0281981 77.604526,5.0729245 77.613497,5.1038512 C 77.616883,5.1164787 77.621999,5.1513102 77.624984,5.1644504 C 77.627768,5.1778446 77.634086,5.2111484 77.636471,5.2250495 C 77.882309,6.8172541 75.61508,11.600927 72.069017,16.752517 C 71.848374,17.07306 71.637752,17.390195 71.416857,17.699951 z "
+         style="color:#000000;fill:url(#linearGradient1540);fill-opacity:1;fill-rule:evenodd;stroke:#3465a4;stroke-width:0.69999981;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <path
+         inkscape:r_cy="true"
+         inkscape:r_cx="true"
+         id="path9888"
+         d="M 76.697261,8.7148938 L 74.026098,6.8762164 C 75.443506,5.2908747 76.722887,4.3117038 77.413414,4.3511484 C 77.417819,4.3514872 77.434616,4.3522365 77.438973,4.3526605 C 77.44328,4.3531691 77.460274,4.3535789 77.464532,4.3541722 C 77.46874,4.354851 77.485934,4.3549196 77.490092,4.3556839 C 77.514737,4.3607826 77.554504,4.375343 77.577307,4.3835542 C 77.581056,4.3850098 77.59166,4.3944343 77.595355,4.3959775 C 77.599,4.3976079 77.617324,4.3957711 77.620915,4.3974898 C 77.624452,4.3992965 77.635479,4.4080185 77.638963,4.4099134 C 77.642394,4.4118966 77.653635,4.4202647 77.657011,4.4223368 C 77.660335,4.4244975 77.671791,4.4325104 77.67506,4.4347604 C 77.678329,4.4370105 77.689904,4.4448509 77.693108,4.4471838 C 77.696249,4.4495983 77.708079,4.4571105 77.711157,4.4596074 C 77.714171,4.4621857 77.726255,4.4693715 77.729205,4.4720307 C 77.732093,4.4747711 77.736919,4.4925441 77.739743,4.4953655 C 77.742504,4.4982671 77.755093,4.5048071 77.757791,4.5077888 C 77.773602,4.5261576 77.8014,4.5581054 77.814963,4.5793067 C 77.817161,4.5829179 77.823364,4.5989533 77.8255,4.6026421 C 77.827574,4.6064079 77.834025,4.6221353 77.836038,4.6259773 C 77.837989,4.6298956 77.844685,4.6453173 77.846575,4.6493122 C 78.129953,5.2802475 77.672078,6.8248978 76.697261,8.7148938 z "
+         style="color:#000000;fill:url(#linearGradient1542);fill-opacity:1;fill-rule:evenodd;stroke:#3465a4;stroke-width:0.69999981;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <path
+         sodipodi:nodetypes="cccszsc"
+         id="path9930"
+         d="M 70.245095,17.972588 C 70.112917,18.159708 69.980402,18.334049 69.849098,18.517294 L 67.224383,16.708474 C 67.58359,16.163635 68.090072,15.27492 68.467754,14.708463 C 72.816017,8.1868296 77.077705,4.9281066 77.255374,5.0497893 C 77.450812,5.1836414 75.740229,10.283755 71.307249,16.444573 C 71.046975,16.806293 70.495538,17.618044 70.245095,17.972588 z "
+         style="opacity:0.35714285;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1544);stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         inkscape:r_cx="true"
+         inkscape:r_cy="true" />
+    </g>
+  </g>
+</svg>
index cabcc9a6a6f4325bece9131aaf425cc5c69f0daf..bb8f696c53f7f8610b7da84771088194427ac2bd 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -1,14 +1,24 @@
 List of features to be implemented (not in any particular order)
 ----------------------------------------------------------------
+- paste text directly into xournal, from xournal?
+    (instead of starting a text item and pasting into it)
+- internationalization / translation of interface
+- integration into desktop environment (document icons/previews? 
+       mime type? click on xoj opens it? list app in start menu?)
+- rewrite printing using GtkPrint + Cairo as GnomePrint replacement
+   (keep GnomePrint option for compatibility with GTK+ <2.10)
+- xournal_page-shadow.diff (Martin Kiefel Feb 5 2007)
+- "organizer" side panel (hierarchy of notes), cf. gjots
 - xoj2pdf on command line
+- 'insert blank page after' command (more useful in PDF annot !)
 - load images as bg if given on command-line (as with PDF on commandline)
 - load PDF pages only on demand (create empty pixmaps at first if can
    parse PDF geometry ourselves, else try pdfinfo ??)
-- de-map space key from button bar
-- lasso selection tool
+   (and config option to limit total memory usage for PDF bitmaps)
+- lasso selection tool (see shoffsta patch)
+     (http://shoffsta.afraid.org/Projects/Xournal/)
 - flatten (incl undo/redo...) - enabled only if nlayers>1
 - resize selection
-- text tool, font chooser, default font
 - color chooser (papercolor, pen color); maybe more default colors
 - printing: print-options, save printer settings (throughout a session,
    and on disk) (maybe a separate config file .xournal/gnome-print-settings)
@@ -19,19 +29,36 @@ List of features to be implemented (not in any particular order)
 - more pen/highlighter shapes (chisel)
 - convert to/from Jarnal format; to/from MS Journal format???
 - recalibration upon screen resize / compensation for miscalibration
+    (use ConfigureNotify event and XInput? cf "Bugs" tracker 08/2007)
 - find a better behavior for vertical space tool across page boundaries ?
-- key mappings (pgup/dn for full page, up/dn for scroll)
-    (customize secondary mappings for tablet button use ?)
+   config options? 1) when there's not enough space at bottom of page:
+                       - resize the page
+                       - move stuff to next page
+                       - move stuff to a new page
+                   2) when moving to another page:
+                       - move everything
+                       - move only what doesn't fit (??? looks hard)
+   option for vert space tool to also move the background??
+   (PDF: cut-and-crop by running PDF code twice with 2 different clipboxes?)
 - copy/paste of an entire page (beware if PDF bg is not compatible!)
 - simple drawing tools: rectangles, ellipses
 - option to save all annotated files within the .xoj
 - non-antialiased version for handhelds
 - customize autogenerated save file names 
-- optimize speed in hand tool (process groups of motion events)?
-   (setting 1 pixel min threshold doesn't help -- look at GTK+ scrollbar code?)
 - layer dialog box to set visibility status of each layer regardless of
   which layer is being edited
 - display corruption on scroll down when bottom of window is obscured??
   (probably a gnomecanvas or X bug -- expose event generated for wrong
   region, or not processed?)
 - bitmap preview for document icon in desktop environments?
+- autosave at a regular interval in a given location
+- keep only a few pages of a PDF file in memory at any given time; generate
+  pages by parsing pdf info rather than generating bitmaps for all of them.
+- win32 port (Matteo Abrate)
+- snap-to-grid tool? (Matteo Abrate)
+- option to auto-save preferences on exit (Michele Codutti)
+- EPOS 7/24/07: Thumbnails pane
+- EPOS: Connect to EPOS api which sends A4 mapped points
+- EPOS: Cut and Paste into OpenOffice applications and the GIMP (as bitmap??)
+- EPOS: Export pages to pictures in the Jpg and Png formats.
+- EPOS: Rotate Ink in custom angle.
index 4ff98dbc132934dd90c84df332f9b73528c93bdb..59afa6c4b2d56040a2ae942c2cbd75ec25a860d3 100644 (file)
@@ -1,8 +1,3 @@
-#define ENABLE_XINPUT_BUGFIX  1
-/* change the above to 0 if you are experiencing calibration problems with
-   XInput and want to try things differently 
-*/
-
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
@@ -33,17 +28,11 @@ void hide_unimplemented(void)
   gtk_widget_hide(GET_COMPONENT("filePrintOptions"));
   gtk_widget_hide(GET_COMPONENT("journalFlatten"));
   gtk_widget_hide(GET_COMPONENT("papercolorOther"));
-  gtk_widget_hide(GET_COMPONENT("toolsText"));
-  gtk_widget_hide(GET_COMPONENT("buttonText"));
-  gtk_widget_hide(GET_COMPONENT("button2Text"));
-  gtk_widget_hide(GET_COMPONENT("button3Text"));
   gtk_widget_hide(GET_COMPONENT("toolsSelectRegion"));
   gtk_widget_hide(GET_COMPONENT("buttonSelectRegion"));
   gtk_widget_hide(GET_COMPONENT("button2SelectRegion"));
   gtk_widget_hide(GET_COMPONENT("button3SelectRegion"));
   gtk_widget_hide(GET_COMPONENT("colorOther"));
-  gtk_widget_hide(GET_COMPONENT("toolsTextFont"));
-  gtk_widget_hide(GET_COMPONENT("toolsDefaultText"));
   gtk_widget_hide(GET_COMPONENT("helpIndex"));
 }
 
@@ -71,6 +60,9 @@ void init_stuff (int argc, char *argv[])
   // initialize preferences
   init_config_default();
   load_config_from_file();
+  ui.font_name = g_strdup(ui.default_font_name);
+  ui.font_size = ui.default_font_size;
+  ui.hiliter_alpha_mask = 0xffffff00 + (guint)(255*ui.hiliter_opacity);
 
   // we need an empty canvas prior to creating the journal structures
   canvas = GNOME_CANVAS (gnome_canvas_new_aa ());
@@ -107,7 +99,7 @@ void init_stuff (int argc, char *argv[])
       b->tool_type = i;
       b->color_rgba = predef_colors_rgba[b->color_no];
       if (i == TOOL_HIGHLIGHTER) {
-        b->color_rgba &= HILITER_ALPHA_MASK;
+        b->color_rgba &= ui.hiliter_alpha_mask;
       }
       b->thickness = predef_thickness[i][b->thickness_no];
     }
@@ -121,6 +113,7 @@ void init_stuff (int argc, char *argv[])
   gtk_window_set_default_size(GTK_WINDOW (winMain), ui.window_default_width, ui.window_default_height);
   if (ui.maximize_at_start) gtk_window_maximize(GTK_WINDOW (winMain));
   update_toolbar_and_menu();
+  update_font_button();
 
   gtk_check_menu_item_set_active(
     GTK_CHECK_MENU_ITEM(GET_COMPONENT("journalApplyAllPages")), ui.bg_apply_all_pages);
@@ -132,6 +125,8 @@ void init_stuff (int argc, char *argv[])
     gtk_window_fullscreen(GTK_WINDOW(winMain));
   }
 
+  allow_all_accels();
+  add_scroll_bindings();
 
   // set up and initialize the canvas
 
@@ -140,7 +135,6 @@ void init_stuff (int argc, char *argv[])
   gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (canvas));
   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (w), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
   gtk_widget_set_events (GTK_WIDGET (canvas), GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
-  gtk_widget_set_extension_events(GTK_WIDGET (canvas), GDK_EXTENSION_EVENTS_ALL);
   gnome_canvas_set_pixels_per_unit (canvas, ui.zoom);
   gnome_canvas_set_center_scroll_region (canvas, TRUE);
   gtk_layout_get_hadjustment(GTK_LAYOUT (canvas))->step_increment = ui.scrollbar_step_increment;
@@ -182,7 +176,7 @@ void init_stuff (int argc, char *argv[])
     device = (GdkDevice *)dev_list->data;
     if (device != gdk_device_get_core_pointer()) {
       /* get around a GDK bug: map the valuator range CORRECTLY to [0,1] */
-#if ENABLE_XINPUT_BUGFIX
+#ifdef ENABLE_XINPUT_BUGFIX
       gdk_device_set_axis_use(device, 0, GDK_AXIS_IGNORE);
       gdk_device_set_axis_use(device, 1, GDK_AXIS_IGNORE);
 #endif
@@ -195,6 +189,8 @@ void init_stuff (int argc, char *argv[])
     gtk_widget_set_sensitive(GET_COMPONENT("optionsUseXInput"), FALSE);
 
   ui.use_xinput = ui.allow_xinput && can_xinput;
+  gtk_widget_set_extension_events(GTK_WIDGET (canvas), 
+    ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
 
   gtk_check_menu_item_set_active(
     GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsUseXInput")), ui.use_xinput);
@@ -215,6 +211,7 @@ void init_stuff (int argc, char *argv[])
   update_undo_redo_enabled();
   update_copy_paste_enabled();
   update_vbox_order(ui.vertical_order[ui.fullscreen?1:0]);
+  gtk_widget_grab_focus(GTK_WIDGET(canvas));
 
   // show everything...
   
diff --git a/src/sft.h b/src/sft.h
new file mode 100644 (file)
index 0000000..bcb3d90
--- /dev/null
+++ b/src/sft.h
@@ -0,0 +1,678 @@
+/* modified from sft.h in libgnomeprint */
+
+/*
+ * Copyright Â© 2002, 2003 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of Sun Microsystems, Inc. nor the names of 
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES OR
+ * LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR RELATING TO USE,
+ * MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS DERIVATIVES.
+ * IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE,
+ * PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE
+ * THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE
+ * SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+/* $Id$ */
+
+/* @(#)sft.h 1.17 03/01/08 SMI */
+
+/*
+ * @file sft.h
+ * @brief Sun Font Tools
+ * @author Alexander Gelfenbain <adg@sun.com>
+ * @version 1.0
+ */
+
+/*
+ *        Generated fonts contain an XUID entry in the form of:
+ *
+ *                  103 0 T C1 N C2 C3
+ *
+ *        103 - Sun's Adobe assigned XUID number. Contact person: Alexander Gelfenbain <gelf@eng.sun.com>
+ *
+ *        T  - font type. 0: Type 3, 1: Type 42
+ *        C1 - CRC-32 of the entire source TrueType font
+ *        N  - number of glyphs in the subset
+ *        C2 - CRC-32 of the array of glyph IDs used to generate the subset
+ *        C3 - CRC-32 of the array of encoding numbers used to generate the subset
+ *
+ */
+
+#ifndef __SUBFONT_H
+#define __SUBFONT_H
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#define false 0               /**< standard false value */
+#define true  1               /**< standard true value */
+
+/* glib already deals with different compilers */
+#include <glibconfig.h>
+
+/*@{*/
+    typedef gint16       F2Dot14;            /**< fixed: 2.14 */
+    typedef gint32       F16Dot16;           /**< fixed: 16.16 */
+/*@}*/
+
+    typedef struct {
+        guint16 s;
+        guint16 d;
+    } uint16pair;
+
+/** Return value of OpenTTFont() and CreateT3FromTTGlyphs() */
+    enum SFErrCodes {
+        SF_OK,                              /**< no error                                     */
+        SF_BADFILE,                         /**< file not found                               */
+        SF_FILEIO,                          /**< file I/O error                               */
+        SF_MEMORY,                          /**< memory allocation error                      */
+        SF_GLYPHNUM,                        /**< incorrect number of glyphs                   */
+        SF_BADARG,                          /**< incorrect arguments                          */
+        SF_TTFORMAT,                        /**< incorrect TrueType font format               */
+        SF_TABLEFORMAT,                     /**< incorrect format of a TrueType table         */
+        SF_FONTNO                           /**< incorrect logical font number of a TTC font  */
+    };
+
+#ifndef FW_THIN /* WIN32 compilation would conflict */
+/** Value of the weight member of the TTGlobalFontInfo struct */
+    enum WeightClass {
+        FW_THIN = 100,                      /**< Thin                               */
+        FW_EXTRALIGHT = 200,                /**< Extra-light (Ultra-light)          */
+        FW_LIGHT = 300,                     /**< Light                              */
+        FW_NORMAL = 400,                    /**< Normal (Regular)                   */
+        FW_MEDIUM = 500,                    /**< Medium                             */
+        FW_SEMIBOLD = 600,                  /**< Semi-bold (Demi-bold)              */
+        FW_BOLD = 700,                      /**< Bold                               */
+        FW_EXTRABOLD = 800,                 /**< Extra-bold (Ultra-bold)            */
+        FW_BLACK = 900                      /**< Black (Heavy)                      */
+    };
+
+/** Value of the width member of the TTGlobalFontInfo struct */
+    enum WidthClass {
+        FWIDTH_ULTRA_CONDENSED = 1,         /**< 50% of normal                      */
+        FWIDTH_EXTRA_CONDENSED = 2,         /**< 62.5% of normal                    */
+        FWIDTH_CONDENSED = 3,               /**< 75% of normal                      */
+        FWIDTH_SEMI_CONDENSED = 4,          /**< 87.5% of normal                    */
+        FWIDTH_NORMAL = 5,                  /**< Medium, 100%                       */
+        FWIDTH_SEMI_EXPANDED = 6,           /**< 112.5% of normal                   */
+        FWIDTH_EXPANDED = 7,                /**< 125% of normal                     */
+        FWIDTH_EXTRA_EXPANDED = 8,          /**< 150% of normal                     */
+        FWIDTH_ULTRA_EXPANDED = 9           /**< 200% of normal                     */
+    };
+#endif /* FW_THIN */
+
+/** Type of the 'kern' table, stored in _TrueTypeFont::kerntype */
+    enum KernType {
+
+        KT_NONE         = 0,                /**< no kern table                      */
+        KT_APPLE_NEW    = 1,                /**< new Apple kern table               */
+        KT_MICROSOFT    = 2                 /**< Microsoft table                    */
+    };
+
+/* Composite glyph flags definition */
+    enum CompositeFlags {
+        ARG_1_AND_2_ARE_WORDS     = 1,
+        ARGS_ARE_XY_VALUES        = 1<<1,
+        ROUND_XY_TO_GRID          = 1<<2,
+        WE_HAVE_A_SCALE           = 1<<3,
+        MORE_COMPONENTS           = 1<<5,
+        WE_HAVE_AN_X_AND_Y_SCALE  = 1<<6,
+        WE_HAVE_A_TWO_BY_TWO      = 1<<7,
+        WE_HAVE_INSTRUCTIONS      = 1<<8,
+        USE_MY_METRICS            = 1<<9,
+        OVERLAP_COMPOUND          = 1<<10
+    };
+
+/** Flags for TrueType generation */
+    enum TTCreationFlags {
+        TTCF_AutoName = 1,                  /**< Automatically generate a compact 'name' table.
+                                               If this flag is not set, name table is generated
+                                               either from an array of NameRecord structs passed as
+                                               arguments or if the array is NULL, 'name' table
+                                               of the generated TrueType file will be a copy
+                                               of the name table of the original file.
+                                               If this flag is set the array of NameRecord structs
+                                               is ignored and a very compact 'name' table is automatically
+                                               generated. */
+
+        TTCF_IncludeOS2 = 2                 /** If this flag is set OS/2 table from the original font will be
+                                                copied to the subset */
+    };
+
+    /** Structure used by GetTTGlyphMetrics() */
+    /*- In horisontal writing mode right sidebearing is calculated using this formula
+     *- rsb = aw - (lsb + xMax - xMin) -*/
+     typedef struct {
+         gint16  xMin;
+         gint16  yMin;
+         gint16  xMax;
+         gint16  yMax;
+         guint16 aw;                /*- Advance Width (horisontal writing mode)    */
+         gint16  lsb;               /*- Left sidebearing (horisontal writing mode) */
+         guint16 ah;                /*- advance height (vertical writing mode)     */
+         gint16  tsb;               /*- top sidebearing (vertical writing mode)    */
+     } TTGlyphMetrics;
+
+
+    /** Structure used by GetTTSimpleGlyphMetrics() and GetTTSimpleCharMetrics() functions */
+    typedef struct {
+        guint16 adv;                         /**< advance width or height            */
+        gint16 sb;                           /**< left or top sidebearing            */
+    } TTSimpleGlyphMetrics;
+
+    /** Structure returned by ReadGlyphMetrics() */
+    typedef struct {
+        guint16 aw, ah;
+        gint16 lsb, tsb;
+    } TTFullSimpleGlyphMetrics;
+
+
+/** Structure used by the TrueType Creator and GetRawGlyphData() */
+
+    typedef struct {
+        guint32 glyphID;                     /**< glyph ID                           */
+        guint16 nbytes;                      /**< number of bytes in glyph data      */
+        guint8  *ptr;                         /**< pointer to glyph data              */
+        guint16 aw;                          /**< advance width                      */
+        gint16  lsb;                         /**< left sidebearing                   */
+        guint16 compflag;                    /**< 0- if non-composite, 1- otherwise  */
+        guint16 npoints;                     /**< number of points                   */
+        guint16 ncontours;                   /**< number of contours                 */
+        /* */
+        guint32 newID;                       /**< used internally by the TTCR        */
+    } GlyphData;
+
+
+    /* STSF defines NameRecord and FUnitBBox structures in its own include file sttypes.h */
+
+    typedef struct {
+        gint16 xMin;
+        gint16 yMin;
+        gint16 xMax;
+        gint16 yMax;
+    } FUnitBBox;
+
+/** Structure used by the TrueType Creator and CreateTTFromTTGlyphs() */
+    typedef struct {
+        guint16 platformID;                  /**< Platform ID                                            */
+        guint16 encodingID;                  /**< Platform-specific encoding ID                          */
+        guint16 languageID;                  /**< Language ID                                            */
+        guint16 nameID;                      /**< Name ID                                                */
+        guint16 slen;                        /**< String length in bytes                                 */
+        guint8  *sptr;                        /**< Pointer to string data (not zero-terminated!)          */
+    } NameRecord;
+
+
+/** Return value of GetTTGlobalFontInfo() */
+
+    typedef struct {
+        char *family;             /**< family name                                             */
+        guint16 *ufamily;                /**< family name UCS2                                         */
+        char *subfamily;          /**< subfamily name                                          */
+        char *psname;             /**< PostScript name                                         */
+        int   weight;             /**< value of WeightClass or 0 if can't be determined        */
+        int   width;              /**< value of WidthClass or 0 if can't be determined         */
+        int   pitch;              /**< 0: proportianal font, otherwise: monospaced             */
+        int   italicAngle;        /**< in counter-clockwise degrees * 65536                    */
+        guint16 fsSelection;       /**< fsSelection field of OS/2 table                         */
+        int   xMin;               /**< global bounding box: xMin                               */
+        int   yMin;               /**< global bounding box: yMin                               */
+        int   xMax;               /**< global bounding box: xMax                               */
+        int   yMax;               /**< global bounding box: yMax                               */
+        int   ascender;           /**< typographic ascent.                                     */
+        int   descender;          /**< typographic descent.                                    */
+        int   linegap;            /**< typographic line gap.\ Negative values are treated as
+                                     zero in Win 3.1, System 6 and System 7.                 */
+        int   vascent;            /**< typographic ascent for vertical writing mode            */
+        int   vdescent;           /**< typographic descent for vertical writing mode           */
+        int   typoAscender;       /**< OS/2 portable typographic ascender                      */
+        int   typoDescender;      /**< OS/2 portable typographic descender                     */
+        int   typoLineGap;        /**< OS/2 portable typographc line gap                       */
+        int   winAscent;          /**< ascender metric for Windows                             */
+        int   winDescent;         /**< descender metric for Windows                            */
+        int   symbolEncoded;      /**< 1: MS symbol encoded 0: not symbol encoded              */
+        int   rangeFlag;          /**< if set to 1 Unicode Range flags are applicable          */
+        guint32 ur1;               /**< bits 0 - 31 of Unicode Range flags                      */
+        guint32 ur2;               /**< bits 32 - 63 of Unicode Range flags                     */
+        guint32 ur3;               /**< bits 64 - 95 of Unicode Range flags                     */
+        guint32 ur4;               /**< bits 96 - 127 of Unicode Range flags                    */
+        guint8   panose[10];        /**< PANOSE classification number                            */
+        guint16 typeFlags;               /**< type flags (copyright information)                      */
+    } TTGlobalFontInfo;
+
+/** Structure used by KernGlyphs()      */
+    typedef struct {
+        int x;                    /**< positive: right, negative: left                        */
+        int y;                    /**< positive: up, negative: down                           */
+    } KernData;
+
+
+/** ControlPoint structure used by GetTTGlyphPoints() */
+    typedef struct {
+        guint32 flags;             /**< 00000000 00000000 e0000000 bbbbbbbb */
+        /**< b - guint8 flags from the glyf array  */
+        /**< e == 0 - regular point              */
+        /**< e == 1 - end contour                */
+        gint16 x;                  /**< X coordinate in EmSquare units      */
+        gint16 y;                  /**< Y coordinate in EmSquare units      */
+    } ControlPoint;
+
+    typedef struct _TrueTypeFont TrueTypeFont;
+
+/*
+ * @defgroup sft Sun Font Tools Exported Functions
+ */
+
+
+/*
+ * Get the number of fonts contained in a TrueType collection
+ * @param  fname - file name
+ * @return number of fonts or zero, if file is not a TTC file.
+ * @ingroup sft
+ */
+    int CountTTCFonts(const char* fname);
+
+
+/*
+ * TrueTypeFont constructor. 
+ * Reads the font file and allocates the memory for the structure.
+ * @param  facenum - logical font number within a TTC file. This value is ignored
+ *                   for TrueType fonts
+ * @return value of SFErrCodes enum
+ * @ingroup sft
+ */
+    int  OpenTTFont(const char *fname, guint32 facenum, TrueTypeFont**);
+
+/*
+ * TrueTypeFont destructor. Deallocates the memory.
+ * @ingroup sft
+ */
+    void CloseTTFont(TrueTypeFont *);
+
+/*
+ * Extracts TrueType control points, and stores them in an allocated array pointed to
+ * by *pointArray. This function returns the number of extracted points.
+ *
+ * @param ttf         pointer to the TrueTypeFont structure
+ * @param glyphID     Glyph ID
+ * @param pointArray  Return value - address of the pointer to the first element of the array
+ *                    of points allocated by the function
+ * @return            Returns the number of points in *pointArray or -1 if glyphID is
+ *                    invalid.
+ * @ingroup sft
+ *
+ */
+int GetTTGlyphPoints(TrueTypeFont *ttf, guint32 glyphID, ControlPoint **pointArray);
+
+/*
+ * Extracts bounding boxes in normalized FUnits (1000/em) for all glyphs in the
+ * font and allocates an array of FUnitBBox structures. There are ttf->nglyphs
+ * elements in the array.
+ *
+ * @param ttf     pointer to the TrueTypeFont structure
+ *
+ * @return        an array of FUnitBBox structures with values normalized to 1000 UPEm
+ *
+ * @ingroup sft
+ */
+FUnitBBox *GetTTGlyphBoundingBoxes(TrueTypeFont *ttf);
+
+/*
+ * Extracts raw glyph data from the 'glyf' table and returns it in an allocated
+ * GlyphData structure.
+ *
+ * @param ttf         pointer to the TrueTypeFont structure
+ * @param glyphID     Glyph ID
+ *
+ * @return            pointer to an allocated GlyphData structure or NULL if
+ *                    glyphID is not present in the font
+ * @ingroup sft
+ *
+ */
+    GlyphData *GetTTRawGlyphData(TrueTypeFont *ttf, guint32 glyphID);
+
+/*
+ * Extracts all Name Records from the font and stores them in an allocated
+ * array of NameRecord structs
+ *
+ * @param ttf       pointer to the TrueTypeFont struct
+ * @param nr        pointer to the array of NameRecord structs
+ *
+ * @return          number of NameRecord structs
+ * @ingroup sft
+ */
+
+    int GetTTNameRecords(TrueTypeFont *ttf, NameRecord **nr);
+
+/*
+ * Deallocates previously allocated array of NameRecords.
+ *
+ * @param nr        array of NameRecord structs
+ * @param n         number of elements in the array
+ *
+ * @ingroup sft
+ */
+    void DisposeNameRecords(NameRecord* nr, int n);
+
+
+#ifndef NO_TYPE3
+/*
+ * Generates a new PostScript Type 3 font and dumps it to <b>outf</b> file.
+ * This functions subsititues glyph 0 for all glyphIDs that are not found in the font.
+ * @param ttf         pointer to the TrueTypeFont structure
+ * @param outf        the resulting font is written to this stream
+ * @param fname       font name for the new font. If it is NULL the PostScript name of the
+ *                    original font will be used
+ * @param glyphArray  pointer to an array of glyphs that are to be extracted from ttf
+ * @param encoding    array of encoding values. encoding[i] specifies the position of the glyph
+ *                    glyphArray[i] in the encoding vector of the resulting Type3 font
+ * @param nGlyphs     number of glyph IDs in glyphArray and encoding values in encoding
+ * @param wmode       writing mode for the output file: 0 - horizontal, 1 - vertical
+ * @return            return the value of SFErrCodes enum
+ * @see               SFErrCodes
+ * @ingroup sft
+ *
+ */
+    int  CreateT3FromTTGlyphs(TrueTypeFont *ttf, FILE *outf, const char *fname, guint16 *glyphArray, guint8 *encoding, int nGlyphs, int wmode);
+#endif
+
+#ifndef NO_TTCR
+/*
+ * Generates a new TrueType font and dumps it to <b>outf</b> file.
+ * This functions subsititues glyph 0 for all glyphIDs that are not found in the font.
+ * @param ttf         pointer to the TrueTypeFont structure
+ * @param fname       file name for the output TrueType font file
+ * @param glyphArray  pointer to an array of glyphs that are to be extracted from ttf. The first
+ *                    element of this array has to be glyph 0 (default glyph)
+ * @param encoding    array of encoding values. encoding[i] specifies character code for
+ *                    the glyphID glyphArray[i]. Character code 0 usually points to a default
+ *                    glyph (glyphID 0)
+ * @param nGlyphs     number of glyph IDs in glyphArray and encoding values in encoding
+ * @param nNameRecs   number of NameRecords for the font, if 0 the name table from the
+ *                    original font will be used
+ * @param nr          array of NameRecords
+ * @param flags       or'ed TTCreationFlags
+ * @return            return the value of SFErrCodes enum
+ * @see               SFErrCodes
+ * @ingroup sft
+ *
+ */
+    int  CreateTTFromTTGlyphs(TrueTypeFont  *ttf,
+                              const char    *fname,
+                              guint16        *glyphArray,
+                              guint8          *encoding,
+                              int            nGlyphs,
+                              int            nNameRecs,
+                              NameRecord    *nr,
+                              guint32        flags);
+#endif
+
+#ifndef NO_TYPE42
+/*
+ * Generates a new PostScript Type42 font and dumps it to <b>outf</b> file.
+ * This functions subsititues glyph 0 for all glyphIDs that are not found in the font.
+ * @param ttf         pointer to the TrueTypeFont structure
+ * @param outf        output stream for a resulting font
+ * @param psname      PostScript name of the resulting font
+ * @param glyphArray  pointer to an array of glyphs that are to be extracted from ttf. The first
+ *                    element of this array has to be glyph 0 (default glyph)
+ * @param encoding    array of encoding values. encoding[i] specifies character code for
+ *                    the glyphID glyphArray[i]. Character code 0 usually points to a default
+ *                    glyph (glyphID 0)
+ * @param nGlyphs     number of glyph IDs in glyphArray and encoding values in encoding
+ * @return            SF_OK - no errors
+ *                    SF_GLYPHNUM - too many glyphs (> 255)
+ *                    SF_TTFORMAT - corrupted TrueType fonts
+ *
+ * @see               SFErrCodes
+ * @ingroup sft
+ *
+ */
+    int  CreateT42FromTTGlyphs(TrueTypeFont  *ttf,
+                               FILE          *outf,
+                               const char    *psname,
+                               guint16        *glyphArray,
+                               guint8          *encoding,
+                               int            nGlyphs);
+#endif
+
+/*
+ * Queries full glyph metrics for one glyph
+ */
+void GetTTGlyphMetrics(TrueTypeFont *ttf, guint32 glyphID, TTGlyphMetrics *metrics);
+
+
+/*
+ * Queries glyph metrics. Allocates an array of TTSimpleGlyphMetrics structs and returns it.
+ *
+ * @param ttf         pointer to the TrueTypeFont structure
+ * @param glyphArray  pointer to an array of glyphs that are to be extracted from ttf
+ * @param nGlyphs     number of glyph IDs in glyphArray and encoding values in encoding
+ * @param mode        writing mode: 0 - horizontal, 1 - vertical
+ * @ingroup sft
+ *
+ */
+TTSimpleGlyphMetrics *GetTTSimpleGlyphMetrics(TrueTypeFont *ttf, guint16 *glyphArray, int nGlyphs, int mode);
+
+#ifndef NO_MAPPERS
+/*
+ * Queries character metrics. Allocates an array of TTSimpleGlyphMetrics structs and returns it.
+ * This function behaves just like GetTTSimpleGlyphMetrics() but it takes a range of Unicode
+ * characters instead of an array of glyphs.
+ *
+ * @param ttf         pointer to the TrueTypeFont structure
+ * @param firstChar   Unicode value of the first character in the range
+ * @param nChars      number of Unicode characters in the range
+ * @param mode        writing mode: 0 - horizontal, 1 - vertical
+ *
+ * @see GetTTSimpleGlyphMetrics
+ * @ingroup sft
+ *
+ */
+    TTSimpleGlyphMetrics *GetTTSimpleCharMetrics(TrueTypeFont *ttf, guint16 firstChar, int nChars, int mode);
+
+/*
+ * Maps a Unicode (UCS-2) string to a glyph array. Returns the number of glyphs in the array,
+ * which for TrueType fonts is always the same as the number of input characters.
+ *
+ * @param ttf         pointer to the TrueTypeFont structure
+ * @param str         pointer to a UCS-2 string
+ * @param nchars      number of characters in <b>str</b>
+ * @param glyphArray  pointer to the glyph array where glyph IDs are to be recorded.
+ *
+ * @return MapString() returns -1 if the TrueType font has no usable 'cmap' tables.
+ *         Otherwise it returns the number of characters processed: <b>nChars</b>
+ *
+ * glyphIDs of TrueType fonts are 2 guint8 positive numbers. glyphID of 0 denotes a missing
+ * glyph and traditionally defaults to an empty square.
+ * glyphArray should be at least sizeof(guint16) * nchars bytes long. If glyphArray is NULL
+ * MapString() replaces the UCS-2 characters in str with glyphIDs.
+ * @ingroup sft
+ */
+#ifdef USE_GSUB
+    int MapString(TrueTypeFont *ttf, guint16 *str, int nchars, guint16 *glyphArray, int bvertical);
+#else
+    int MapString(TrueTypeFont *ttf, guint16 *str, int nchars, guint16 *glyphArray);
+#endif
+
+/*
+ * Maps a Unicode (UCS-2) character to a glyph ID and returns it. Missing glyph has
+ * a glyphID of 0 so this function can be used to test if a character is encoded in the font.
+ *
+ * @param ttf         pointer to the TrueTypeFont structure
+ * @param ch          Unicode (UCS-2) character
+ * @return glyph ID, if the character is missing in the font, the return value is 0.
+ * @ingroup sft
+ */
+#ifdef USE_GSUB
+    guint16 MapChar(TrueTypeFont *ttf, guint16 ch, int bvertical);
+#else
+    guint16 MapChar(TrueTypeFont *ttf, guint16 ch);
+#endif
+#endif
+
+/*
+ * Returns global font information about the TrueType font.
+ * @see TTGlobalFontInfo
+ *
+ * @param ttf         pointer to a TrueTypeFont structure
+ * @param info        pointer to a TTGlobalFontInfo structure
+ * @ingroup sft
+ *
+ */
+    void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info);
+
+/*
+ * Returns kerning information for an array of glyphs.
+ * Kerning is not cumulative.
+ * kern[i] contains kerning information for a pair of glyphs at positions i and i+1
+ *
+ * @param ttf         pointer to a TrueTypeFont structure
+ * @param glyphs      array of source glyphs
+ * @param nglyphs     number of glyphs in the array
+ * @param wmode       writing mode: 0 - horizontal, 1 - vertical
+ * @param kern        array of KernData structures. It should contain nglyphs-1 elements
+ * @see KernData
+ * @ingroup sft
+ *
+ */
+void KernGlyphs(TrueTypeFont *ttf, guint16 *glyphs, int nglyphs, int wmode, KernData *kern);
+
+/*
+ * Returns nonzero if font is a symbol encoded font
+ */
+int CheckSymbolEncoding(TrueTypeFont* ttf);
+
+/*
+ * Extracts a 'cmap' table from a font, allocates memory for it and returns a pointer to it.
+ * DEPRECATED - use ExtractTable instead
+ */
+#if 0
+guint8 *ExtractCmap(TrueTypeFont *ttf);
+#endif
+
+/*
+ * Extracts a table from a font, allocates memort for it and returns a pointer to it.
+ */
+guint8 *ExtractTable(TrueTypeFont *ttf, guint32 tag);
+
+/*
+ * Returns a pointer to the table but does not allocate memory for it.
+ */
+const guint8 *GetTable(TrueTypeFont *ttf, guint32 tag);
+
+/*
+ * Functions that do not use TrueTypeFont structure
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+/*
+ * Reads full (vertical and horisontal) glyph metrics for an array of glyphs from hmtx and vmtx tables
+ *
+ * @param hmtx       TrueType hmtx table
+ * @param vmtx       TrueType vmtx table
+ * @param hcount     numberOfHMetrics value
+ * @param vcount     numOfLongVerMetrics value
+ * @param gcount     total number of glyphs in the font
+ * @param UPEm       units per Em value
+ * @param glyphArray array of source glyph IDs
+ * @param nGlyphs    number of glyphs in the glyphArray array
+ *
+ * @return           array of TTFullSimpleGlyphMetrics data structures
+ *
+ */
+
+TTFullSimpleGlyphMetrics *ReadGlyphMetrics(guint8 *hmtx, guint8 *vmtx, int hcount, int vcount, int gcount, int UPEm, guint16 *glyphArray, int nGlyphs);
+
+void ReadSingleGlyphMetrics(guint8 *hmtx, guint8 *vmtx, int hcount, int vcount, int gcount, int UPEm, guint16 glyphID, TTFullSimpleGlyphMetrics *metrics);
+
+
+/*
+ * Returns the length of the 'kern' subtable
+ *
+ * @param kern       pointer to the 'kern' subtable
+ *
+ * @return           number of bytes in it
+ */
+guint32 GetKernSubtableLength(guint8 *kern);
+
+/*
+ *  Kerns a pair of glyphs.
+ *
+ * @param kerntype   type of the kern table
+ * @param nkern      number of kern subtables
+ * @param kern       array of pointers to kern subtables
+ * @pram unitsPerEm  units per Em value
+ * @param wmode      writing mode: 0 - horizontal, 1 - vertical
+ * @param a          ID of the first glyoh
+ * @param b          ID of the second glyoh
+ * @param x          X-axis kerning value is returned here
+ * @param y          Y-axis kerning value is returned here
+ */
+void KernGlyphPair(int kerntype, guint32 nkern, guint8 **kern, int unitsPerEm, int wmode, guint32 a, guint32 b, int *x, int *y);
+
+
+
+/*- private definitions */ /*FOLD00*/
+
+struct _TrueTypeFont {
+    guint32 tag;
+
+    char   *fname;
+    off_t  fsize;
+    guint8   *ptr;
+
+    char   *psname;
+    char   *family;
+    guint16  *ufamily;
+    char   *subfamily;
+
+    guint32 ntables;
+    guint32 tdoffset;                              /* offset to the table directory (!= 0 for TrueType collections)      */
+    guint32 *goffsets;
+    int    nglyphs;
+    int    unitsPerEm;
+    int    numberOfHMetrics;
+    int    numOfLongVerMetrics;                   /* if this number is not 0, font has vertical metrics information */
+    guint8   *cmap;
+    int    cmapType;
+    guint16 (*mapper)(const guint8 *, guint16);       /* character to glyphID translation function                          */
+    void   **tables;                              /* array of pointers to tables                                        */
+    guint32 *tlens;                                /* array of table lengths                                             */
+    int    kerntype;                              /* Defined in the KernType enum                                       */
+    guint32 nkern;                                 /* number of kern subtables                                           */
+    guint8   **kerntables;                          /* array of pointers to kern subtables                                */
+#ifdef USE_GSUB
+    void   *pGSubstitution;                       /* info provided by GSUB for UseGSUB()                                */
+#endif
+#if 0
+    GnomePrintBuffer gp_buf;
+#endif
+};
+
+#endif /* __SUBFONT_H */
index 038507ad4724ae69c38de812836065d787d0dc2d..2fa9d7c869fbedfc0d26ee1ed2793f7d95994c57 100644 (file)
@@ -23,6 +23,8 @@ void
 on_fileNew_activate                    (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   if (close_journal()) {
     new_journal();
     ui.zoom = ui.startup_zoom;
@@ -43,6 +45,8 @@ on_fileNewBackground_activate          (GtkMenuItem     *menuitem,
   int file_domain;
   gboolean success;
   
+  end_text();
+  reset_focus();
   if (!ok_to_close()) return; // user aborted on save confirmation
   
   dialog = gtk_file_chooser_dialog_new("Open PDF", GTK_WINDOW (winMain),
@@ -55,6 +59,7 @@ on_fileNewBackground_activate          (GtkMenuItem     *menuitem,
   filt_pdf = gtk_file_filter_new();
   gtk_file_filter_set_name(filt_pdf, "PDF files");
   gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
+  gtk_file_filter_add_pattern(filt_pdf, "*.PDF");
   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
 
@@ -111,6 +116,8 @@ on_fileOpen_activate                   (GtkMenuItem     *menuitem,
   char *filename;
   gboolean success;
   
+  end_text();
+  reset_focus();
   if (!ok_to_close()) return; // user aborted on save confirmation
   
   dialog = gtk_file_chooser_dialog_new("Open Journal", GTK_WINDOW (winMain),
@@ -156,6 +163,8 @@ on_fileSave_activate                   (GtkMenuItem     *menuitem,
 {
   GtkWidget *dialog;
   
+  end_text();
+  reset_focus();
   if (ui.filename == NULL) {
     on_fileSaveAs_activate(menuitem, user_data);
     return;
@@ -187,6 +196,8 @@ on_fileSaveAs_activate                 (GtkMenuItem     *menuitem,
   gboolean warn;
   struct stat stat_buf;
   
+  end_text();
+  reset_focus();
   dialog = gtk_file_chooser_dialog_new("Save Journal", GTK_WINDOW (winMain),
      GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
      GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
@@ -287,6 +298,8 @@ on_filePrint_activate                  (GtkMenuItem     *menuitem,
   guchar *s;
   GnomePrintConfig *config = gnome_print_config_default();
 
+  end_text();
+  reset_focus();
   if (ui.filename!=NULL) {
     if (g_str_has_suffix(ui.filename, ".xoj")) {
       in_fn = g_strdup(ui.filename);
@@ -369,6 +382,8 @@ on_filePrintPDF_activate               (GtkMenuItem     *menuitem,
   int response;
   gboolean warn;
   
+  end_text();
+  reset_focus();
   dialog = gtk_file_chooser_dialog_new("Export to PDF", GTK_WINDOW (winMain),
      GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
      GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
@@ -397,6 +412,7 @@ on_filePrintPDF_activate               (GtkMenuItem     *menuitem,
   filt_pdf = gtk_file_filter_new();
   gtk_file_filter_set_name(filt_pdf, "PDF files");
   gtk_file_filter_add_pattern(filt_pdf, "*.pdf");
+  gtk_file_filter_add_pattern(filt_pdf, "*.PDF");
   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
   gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
@@ -438,6 +454,8 @@ void
 on_fileQuit_activate                   (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   if (ok_to_close()) gtk_main_quit ();
 }
 
@@ -453,10 +471,13 @@ on_editUndo_activate                   (GtkMenuItem     *menuitem,
   struct Brush tmp_brush;
   struct Background *tmp_bg;
   double tmp_x, tmp_y;
+  gchar *tmpstr;
   
+  end_text();
+  reset_focus();
   if (undo == NULL) return; // nothing to undo!
   reset_selection(); // safer
-  if (undo->type == ITEM_STROKE) {
+  if (undo->type == ITEM_STROKE || undo->type == ITEM_TEXT) {
     // we're keeping the stroke info, but deleting the canvas item
     gtk_object_destroy(GTK_OBJECT(undo->item->canvas_item));
     undo->item->canvas_item = NULL;
@@ -476,11 +497,8 @@ on_editUndo_activate                   (GtkMenuItem     *menuitem,
         undo->layer->nitems--;
       }
       // recreate the deleted one
-      erasure->item->canvas_item = gnome_canvas_item_new(undo->layer->group,
-             gnome_canvas_line_get_type(), "points", erasure->item->path,
-             "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-             "fill-color-rgba", erasure->item->brush.color_rgba,
-             "width-units", erasure->item->brush.thickness, NULL);
+      make_canvas_item_one(undo->layer->group, erasure->item);
+      
       undo->layer->items = g_list_insert(undo->layer->items, erasure->item,
                                                              erasure->npos);
       if (erasure->npos == 0)
@@ -592,16 +610,9 @@ on_editUndo_activate                   (GtkMenuItem     *menuitem,
                                      (undo->val >= 0) ? undo->val:0);
     undo->page->nlayers++;
     
-    for (itemlist = undo->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
-      it = (struct Item *)itemlist->data;
-      if (it->type == ITEM_STROKE) {
-        it->canvas_item = gnome_canvas_item_new(undo->layer->group,
-            gnome_canvas_line_get_type(), "points", it->path,
-            "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-            "fill-color-rgba", it->brush.color_rgba,
-            "width-units", it->brush.thickness, NULL);
-      }
-    }
+    for (itemlist = undo->layer->items; itemlist!=NULL; itemlist = itemlist->next)
+      make_canvas_item_one(undo->layer->group, (struct Item *)itemlist->data);
+
     do_switch_page(ui.pageno, FALSE, FALSE); // show the restored layer & others...
   }
   else if (undo->type == ITEM_REPAINTSEL) {
@@ -615,8 +626,33 @@ on_editUndo_activate                   (GtkMenuItem     *menuitem,
         gnome_canvas_item_set(it->canvas_item, 
           "fill-color-rgba", it->brush.color_rgba,
           "width-units", it->brush.thickness, NULL);
+      if (it->type == ITEM_TEXT && it->canvas_item != NULL)
+        gnome_canvas_item_set(it->canvas_item, 
+          "fill-color-rgba", it->brush.color_rgba, NULL);
     }
   }
+  else if (undo->type == ITEM_TEXT_EDIT) {
+    tmpstr = undo->str;
+    undo->str = undo->item->text;
+    undo->item->text = tmpstr;
+    gnome_canvas_item_set(undo->item->canvas_item, "text", tmpstr, NULL);
+    update_item_bbox(undo->item);
+  }
+  else if (undo->type == ITEM_TEXT_ATTRIB) {
+    tmpstr = undo->str;
+    undo->str = undo->item->font_name;
+    undo->item->font_name = tmpstr;
+    tmp_x = undo->val_x;
+    undo->val_x = undo->item->font_size;
+    undo->item->font_size = tmp_x;
+    g_memmove(&tmp_brush, undo->brush, sizeof(struct Brush));
+    g_memmove(undo->brush, &(undo->item->brush), sizeof(struct Brush));
+    g_memmove(&(undo->item->brush), &tmp_brush, sizeof(struct Brush));
+    gnome_canvas_item_set(undo->item->canvas_item, 
+      "fill-color-rgba", undo->item->brush.color_rgba, NULL);
+    update_text_item_displayfont(undo->item);
+    update_item_bbox(undo->item);
+  }
   
   // move item from undo to redo stack
   u = undo;
@@ -641,16 +677,15 @@ on_editRedo_activate                   (GtkMenuItem     *menuitem,
   struct Background *tmp_bg;
   struct Layer *l;
   double tmp_x, tmp_y;
+  gchar *tmpstr;
   
+  end_text();
+  reset_focus();
   if (redo == NULL) return; // nothing to redo!
   reset_selection(); // safer
-  if (redo->type == ITEM_STROKE) {
+  if (redo->type == ITEM_STROKE || redo->type == ITEM_TEXT) {
     // re-create the canvas_item
-    redo->item->canvas_item = gnome_canvas_item_new(redo->layer->group,
-     gnome_canvas_line_get_type(), "points", redo->item->path,
-     "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-     "fill-color-rgba", redo->item->brush.color_rgba,
-     "width-units", redo->item->brush.thickness, NULL);
+    make_canvas_item_one(redo->layer->group, redo->item);
     // reinsert the item on its layer
     redo->layer->items = g_list_append(redo->layer->items, redo->item);
     redo->layer->nitems++;
@@ -662,11 +697,7 @@ on_editRedo_activate                   (GtkMenuItem     *menuitem,
       // re-create all the created items
       for (itemlist = erasure->replacement_items; itemlist!=NULL; itemlist = itemlist->next) {
         it = (struct Item *)itemlist->data;
-        it->canvas_item = gnome_canvas_item_new(redo->layer->group,
-             gnome_canvas_line_get_type(), "points", it->path,
-             "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-             "fill-color-rgba", it->brush.color_rgba,
-             "width-units", it->brush.thickness, NULL);
+        make_canvas_item_one(redo->layer->group, it);
         redo->layer->items = g_list_insert_before(redo->layer->items, target, it);
         redo->layer->nitems++;
         lower_canvas_item_to(redo->layer->group, it->canvas_item, erasure->item->canvas_item);
@@ -759,11 +790,7 @@ on_editRedo_activate                   (GtkMenuItem     *menuitem,
   else if (redo->type == ITEM_PASTE) {
     for (itemlist = redo->itemlist; itemlist != NULL; itemlist = itemlist->next) {
       it = (struct Item *)itemlist->data;
-      it->canvas_item = gnome_canvas_item_new(redo->layer->group,
-           gnome_canvas_line_get_type(), "points", it->path,
-           "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-           "fill-color-rgba", it->brush.color_rgba,
-           "width-units", it->brush.thickness, NULL);
+      make_canvas_item_one(redo->layer->group, it);
       redo->layer->items = g_list_append(redo->layer->items, it);
       redo->layer->nitems++;
     }
@@ -805,8 +832,33 @@ on_editRedo_activate                   (GtkMenuItem     *menuitem,
         gnome_canvas_item_set(it->canvas_item, 
           "fill-color-rgba", it->brush.color_rgba,
           "width-units", it->brush.thickness, NULL);
+      if (it->type == ITEM_TEXT && it->canvas_item != NULL)
+        gnome_canvas_item_set(it->canvas_item, 
+          "fill-color-rgba", it->brush.color_rgba, NULL);
     }
   }
+  else if (redo->type == ITEM_TEXT_EDIT) {
+    tmpstr = redo->str;
+    redo->str = redo->item->text;
+    redo->item->text = tmpstr;
+    gnome_canvas_item_set(redo->item->canvas_item, "text", tmpstr, NULL);
+    update_item_bbox(redo->item);
+  }
+  else if (redo->type == ITEM_TEXT_ATTRIB) {
+    tmpstr = redo->str;
+    redo->str = redo->item->font_name;
+    redo->item->font_name = tmpstr;
+    tmp_x = redo->val_x;
+    redo->val_x = redo->item->font_size;
+    redo->item->font_size = tmp_x;
+    g_memmove(&tmp_brush, redo->brush, sizeof(struct Brush));
+    g_memmove(redo->brush, &(redo->item->brush), sizeof(struct Brush));
+    g_memmove(&(redo->item->brush), &tmp_brush, sizeof(struct Brush));
+    gnome_canvas_item_set(redo->item->canvas_item, 
+      "fill-color-rgba", redo->item->brush.color_rgba, NULL);
+    update_text_item_displayfont(redo->item);
+    update_item_bbox(redo->item);
+  }
   
   // move item from redo to undo stack
   u = redo;
@@ -823,6 +875,8 @@ void
 on_editCut_activate                    (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   selection_to_clip();
   selection_delete();
 }
@@ -832,6 +886,8 @@ void
 on_editCopy_activate                   (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   selection_to_clip();
 }
 
@@ -840,6 +896,8 @@ void
 on_editPaste_activate                  (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   clipboard_paste();
 }
 
@@ -848,6 +906,8 @@ void
 on_editDelete_activate                 (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   selection_delete();
 }
 
@@ -860,6 +920,7 @@ on_viewContinuous_activate             (GtkMenuItem     *menuitem,
   double yscroll;
   struct Page *pg;
 
+  reset_focus();
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
   if (ui.view_continuous) return;
   ui.view_continuous = TRUE;
@@ -880,6 +941,7 @@ on_viewOnePage_activate                (GtkMenuItem     *menuitem,
   GtkAdjustment *v_adj;
   double yscroll;
   
+  reset_focus();
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
   if (!ui.view_continuous) return;
   ui.view_continuous = FALSE;
@@ -896,9 +958,11 @@ void
 on_viewZoomIn_activate                 (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  reset_focus();
   if (ui.zoom > MAX_ZOOM) return;
   ui.zoom *= ui.zoom_step_factor;
   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+  rescale_text_items();
   rescale_bg_pixmaps();
 }
 
@@ -907,9 +971,11 @@ void
 on_viewZoomOut_activate                (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  reset_focus();
   if (ui.zoom < MIN_ZOOM) return;
   ui.zoom /= ui.zoom_step_factor;
   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+  rescale_text_items();
   rescale_bg_pixmaps();
 }
 
@@ -918,8 +984,10 @@ void
 on_viewNormalSize_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  reset_focus();
   ui.zoom = DEFAULT_ZOOM;
   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+  rescale_text_items();
   rescale_bg_pixmaps();
 }
 
@@ -928,8 +996,10 @@ void
 on_viewPageWidth_activate              (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  reset_focus();
   ui.zoom = (GTK_WIDGET(canvas))->allocation.width/ui.cur_page->width;
   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+  rescale_text_items();
   rescale_bg_pixmaps();
 }
 
@@ -938,6 +1008,8 @@ void
 on_viewFirstPage_activate              (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   do_switch_page(0, TRUE, FALSE);
 }
 
@@ -946,6 +1018,8 @@ void
 on_viewPreviousPage_activate           (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   if (ui.pageno == 0) return;
   do_switch_page(ui.pageno-1, TRUE, FALSE);
 }
@@ -955,6 +1029,8 @@ void
 on_viewNextPage_activate               (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   if (ui.pageno == journal.npages-1) { // create a page at end
     if (page_ops_forbidden()) return;
     on_journalNewPageEnd_activate(menuitem, user_data);
@@ -968,6 +1044,8 @@ void
 on_viewLastPage_activate               (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   do_switch_page(journal.npages-1, TRUE, FALSE);
 }
 
@@ -976,6 +1054,8 @@ void
 on_viewShowLayer_activate              (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   if (ui.layerno == ui.cur_page->nlayers-1) return;
   reset_selection();
   ui.layerno++;
@@ -989,6 +1069,8 @@ void
 on_viewHideLayer_activate              (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   if (ui.layerno == -1) return;
   reset_selection();
   gnome_canvas_item_hide(GNOME_CANVAS_ITEM(ui.cur_layer->group));
@@ -1005,6 +1087,8 @@ on_journalNewPageBefore_activate       (GtkMenuItem     *menuitem,
 {
   struct Page *pg;
 
+  end_text();
+  reset_focus();
   if (page_ops_forbidden()) return;
   reset_selection();
   pg = new_page(ui.cur_page);
@@ -1025,6 +1109,8 @@ on_journalNewPageAfter_activate        (GtkMenuItem     *menuitem,
 {
   struct Page *pg;
 
+  end_text();
+  reset_focus();
   if (page_ops_forbidden()) return;
   reset_selection();
   pg = new_page(ui.cur_page);
@@ -1045,6 +1131,8 @@ on_journalNewPageEnd_activate          (GtkMenuItem     *menuitem,
 {
   struct Page *pg;
 
+  end_text();
+  reset_focus();
   if (page_ops_forbidden()) return;
   reset_selection();
   pg = new_page((struct Page *)g_list_last(journal.pages)->data);
@@ -1066,6 +1154,8 @@ on_journalDeletePage_activate          (GtkMenuItem     *menuitem,
   GList *layerlist, *itemlist;
   struct Layer *l;
 
+  end_text();
+  reset_focus();
   if (page_ops_forbidden()) return;
   if (journal.npages == 1) return;
   reset_selection();  
@@ -1100,6 +1190,8 @@ on_journalNewLayer_activate            (GtkMenuItem     *menuitem,
 {
   struct Layer *l;
   
+  end_text();
+  reset_focus();
   reset_selection();
   l = g_new(struct Layer, 1);
   l->items = NULL;
@@ -1128,6 +1220,8 @@ on_journalDeleteLayer_activate         (GtkMenuItem     *menuitem,
 {
   GList *list;
   
+  end_text();
+  reset_focus();
   if (ui.cur_layer == NULL) return;
   reset_selection();
   prepare_new_undo();
@@ -1199,6 +1293,8 @@ on_journalPaperSize_activate           (GtkMenuItem     *menuitem,
   struct Page *pg;
   GList *pglist;
   
+  end_text();
+  reset_focus();
   papersize_dialog = create_papersizeDialog();
   papersize_width = ui.cur_page->width;
   papersize_height = ui.cur_page->height;
@@ -1248,6 +1344,8 @@ void
 on_papercolorWhite_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_papercolor_activate(menuitem, COLOR_WHITE);
 }
 
@@ -1256,6 +1354,8 @@ void
 on_papercolorYellow_activate           (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_papercolor_activate(menuitem, COLOR_YELLOW);
 }
 
@@ -1264,6 +1364,8 @@ void
 on_papercolorPink_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_papercolor_activate(menuitem, COLOR_RED);
 }
 
@@ -1272,6 +1374,8 @@ void
 on_papercolorOrange_activate           (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_papercolor_activate(menuitem, COLOR_ORANGE);
 }
 
@@ -1280,6 +1384,8 @@ void
 on_papercolorBlue_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_papercolor_activate(menuitem, COLOR_BLUE);
 }
 
@@ -1288,6 +1394,8 @@ void
 on_papercolorGreen_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_papercolor_activate(menuitem, COLOR_GREEN);
 }
 
@@ -1304,6 +1412,8 @@ void
 on_paperstylePlain_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_paperstyle_activate(menuitem, RULING_NONE);
 }
 
@@ -1312,6 +1422,8 @@ void
 on_paperstyleLined_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_paperstyle_activate(menuitem, RULING_LINED);
 }
 
@@ -1320,6 +1432,8 @@ void
 on_paperstyleRuled_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_paperstyle_activate(menuitem, RULING_RULED);
 }
 
@@ -1328,6 +1442,8 @@ void
 on_paperstyleGraph_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   process_paperstyle_activate(menuitem, RULING_GRAPH);
 }
 
@@ -1345,6 +1461,8 @@ on_journalLoadBackground_activate      (GtkMenuItem     *menuitem,
   char *filename;
   gboolean attach;
   
+  end_text();
+  reset_focus();
   dialog = gtk_file_chooser_dialog_new("Open Background", GTK_WINDOW (winMain),
      GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
      GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
@@ -1368,7 +1486,9 @@ on_journalLoadBackground_activate      (GtkMenuItem     *menuitem,
   filt_pspdf = gtk_file_filter_new();
   gtk_file_filter_set_name(filt_pspdf, "PS/PDF files (as bitmaps)");
   gtk_file_filter_add_pattern(filt_pspdf, "*.ps");
+  gtk_file_filter_add_pattern(filt_pspdf, "*.PS");
   gtk_file_filter_add_pattern(filt_pspdf, "*.pdf");
+  gtk_file_filter_add_pattern(filt_pspdf, "*.PDF");
   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pspdf);
 
   attach_opt = gtk_check_button_new_with_label("Attach file to the journal");
@@ -1444,6 +1564,7 @@ on_journalLoadBackground_activate      (GtkMenuItem     *menuitem,
   if (ui.zoom != DEFAULT_ZOOM) {
     ui.zoom = DEFAULT_ZOOM;
     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+    rescale_text_items();
     rescale_bg_pixmaps();
   }
   do_switch_page(ui.pageno, TRUE, TRUE);
@@ -1455,6 +1576,8 @@ on_journalScreenshot_activate          (GtkMenuItem     *menuitem,
 {
   struct Background *bg;
   
+  end_text();
+  reset_focus();
   reset_selection();
   gtk_window_iconify(GTK_WINDOW(winMain)); // hide ourselves
   gdk_display_sync(gdk_display_get_default());
@@ -1488,6 +1611,7 @@ on_journalScreenshot_activate          (GtkMenuItem     *menuitem,
   if (ui.zoom != DEFAULT_ZOOM) {
     ui.zoom = DEFAULT_ZOOM;
     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+    rescale_text_items();
     rescale_bg_pixmaps();
   }
   do_switch_page(ui.pageno, TRUE, TRUE);
@@ -1500,6 +1624,8 @@ on_journalApplyAllPages_activate       (GtkMenuItem     *menuitem,
 {
   gboolean active;
   
+  end_text();
+  reset_focus();
   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
   if (active == ui.bg_apply_all_pages) return;
   ui.bg_apply_all_pages = active;
@@ -1551,6 +1677,8 @@ on_toolsPen_activate                   (GtkMenuItem     *menuitem,
   if (ui.cur_mapping != 0) return;
   if (ui.toolno[0] == TOOL_PEN) return;
 
+  end_text();
+  reset_focus();
   reset_selection();
   ui.toolno[0] = TOOL_PEN;
   ui.ruler[0] = FALSE;
@@ -1578,6 +1706,8 @@ on_toolsEraser_activate                (GtkMenuItem     *menuitem,
   if (ui.cur_mapping != 0) return;
   if (ui.toolno[0] == TOOL_ERASER) return;
   
+  end_text();
+  reset_focus();
   reset_selection();
   ui.toolno[0] = TOOL_ERASER;
   ui.ruler[0] = FALSE;
@@ -1605,6 +1735,8 @@ on_toolsHighlighter_activate           (GtkMenuItem     *menuitem,
   if (ui.cur_mapping != 0) return; // not user-generated
   if (ui.toolno[0] == TOOL_HIGHLIGHTER) return;
   
+  end_text();
+  reset_focus();
   reset_selection();
   ui.toolno[0] = TOOL_HIGHLIGHTER;
   ui.ruler[0] = FALSE;
@@ -1621,7 +1753,27 @@ void
 on_toolsText_activate                  (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-
+  if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
+    if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
+      return;
+  } else {
+    if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
+      return;
+  }
+  
+  if (ui.cur_mapping != 0) return; // not user-generated
+  if (ui.toolno[0] == TOOL_TEXT) return;
+  
+  reset_focus();
+  reset_selection();
+  ui.toolno[0] = TOOL_TEXT;
+  ui.ruler[0] = FALSE;
+  ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
+  update_mapping_linkings(-1);
+  update_tool_buttons();
+  update_tool_menu();
+  update_color_menu();
+  update_cursor();
 }
 
 
@@ -1648,6 +1800,8 @@ on_toolsSelectRectangle_activate       (GtkMenuItem     *menuitem,
   if (ui.cur_mapping != 0) return; // not user-generated
   if (ui.toolno[0] == TOOL_SELECTRECT) return;
   
+  end_text();
+  reset_focus();
   ui.toolno[0] = TOOL_SELECTRECT;
   ui.ruler[0] = FALSE;
   update_mapping_linkings(-1);
@@ -1673,6 +1827,8 @@ on_toolsVerticalSpace_activate         (GtkMenuItem     *menuitem,
   if (ui.cur_mapping != 0) return; // not user-generated
   if (ui.toolno[0] == TOOL_VERTSPACE) return;
   
+  end_text();
+  reset_focus();
   reset_selection();
   ui.toolno[0] = TOOL_VERTSPACE;
   ui.ruler[0] = FALSE;
@@ -1850,6 +2006,8 @@ on_eraserStandard_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
+  end_text();
+  reset_focus();
   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STANDARD;
   update_mapping_linkings(TOOL_ERASER);
 }
@@ -1860,6 +2018,8 @@ on_eraserWhiteout_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
+  end_text();
+  reset_focus();
   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_WHITEOUT;
   update_mapping_linkings(TOOL_ERASER);
 }
@@ -1870,6 +2030,8 @@ on_eraserDeleteStrokes_activate        (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem))) return;
+  end_text();
+  reset_focus();
   ui.brushes[0][TOOL_ERASER].tool_options = TOOLOPT_ERASER_STROKES;
   update_mapping_linkings(TOOL_ERASER);
 }
@@ -1903,15 +2065,30 @@ void
 on_toolsTextFont_activate              (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-
-}
-
+  GtkWidget *dialog;
+  gchar *str;
+  
+  dialog = gtk_font_selection_dialog_new("Select Font");
+  str = make_cur_font_name();
+  gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(dialog), str);
+  g_free(str);
+  if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
+    gtk_widget_destroy(dialog);
+    reset_focus();
+    return;
+  }
+  str = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(dialog));
+  gtk_widget_destroy(dialog);
+  process_font_sel(str);
+}    
 
 void
 on_toolsDefaultPen_activate            (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
   switch_mapping(0);
+  end_text();
+  reset_focus();
   reset_selection();
   g_memmove(&(ui.brushes[0][TOOL_PEN]), ui.default_brushes+TOOL_PEN, sizeof(struct Brush));
   ui.toolno[0] = TOOL_PEN;
@@ -1931,6 +2108,8 @@ on_toolsDefaultEraser_activate         (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
   switch_mapping(0);
+  end_text();
+  reset_focus();
   reset_selection();
   g_memmove(&(ui.brushes[0][TOOL_ERASER]), ui.default_brushes+TOOL_ERASER, sizeof(struct Brush));
   ui.toolno[0] = TOOL_ERASER;
@@ -1950,6 +2129,8 @@ on_toolsDefaultHighlighter_activate    (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
   switch_mapping(0);
+  end_text();
+  reset_focus();
   reset_selection();
   g_memmove(&(ui.brushes[0][TOOL_HIGHLIGHTER]), ui.default_brushes+TOOL_HIGHLIGHTER, sizeof(struct Brush));
   ui.toolno[0] = TOOL_HIGHLIGHTER;
@@ -1967,7 +2148,27 @@ void
 on_toolsDefaultText_activate           (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-
+  switch_mapping(0);
+  if (ui.toolno[0]!=TOOL_TEXT) end_text();
+  reset_focus();
+  reset_selection();
+  ui.toolno[0] = TOOL_TEXT;
+  ui.ruler[0] = FALSE;
+  ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
+  ui.cur_brush->color_no = ui.default_brushes[TOOL_PEN].color_no;
+  ui.cur_brush->color_rgba = ui.default_brushes[TOOL_PEN].color_rgba;
+  g_free(ui.font_name);
+  ui.font_name = g_strdup(ui.default_font_name);
+  ui.font_size = ui.default_font_size;
+  if (ui.cur_item_type == ITEM_TEXT) {
+    refont_text_item(ui.cur_item, ui.font_name, ui.font_size);
+  }
+  update_font_button();
+  update_mapping_linkings(-1);
+  update_tool_buttons();
+  update_tool_menu();
+  update_color_menu();
+  update_cursor();
 }
 
 
@@ -1975,9 +2176,30 @@ void
 on_toolsSetAsDefault_activate          (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  struct Item *it;
+  
   if (ui.cur_mapping!=0) return;
   if (ui.toolno[0] < NUM_STROKE_TOOLS)
     g_memmove(ui.default_brushes+ui.toolno[0], &(ui.brushes[0][ui.toolno[0]]), sizeof(struct Brush));
+  if (ui.toolno[0] == TOOL_TEXT) {
+    if (ui.cur_item_type == ITEM_TEXT) {
+      g_free(ui.font_name);
+      ui.font_name = g_strdup(ui.cur_item->font_name);
+      ui.font_size = ui.cur_item->font_size;
+    }
+    else if (ui.selection!=NULL && ui.selection->items!=NULL &&
+             ui.selection->items->next==NULL &&
+             (it=(struct Item*)ui.selection->items->data)->type == ITEM_TEXT) {
+      g_free(ui.font_name);
+      ui.font_name = g_strdup(it->font_name);
+      ui.font_size = it->font_size;
+    }
+    g_free(ui.default_font_name);
+    ui.default_font_name = g_strdup(ui.font_name);
+    ui.default_font_size = ui.font_size;
+  }
+  end_text();
+  reset_focus();
 }
 
 
@@ -1995,6 +2217,8 @@ on_toolsRuler_activate                 (GtkMenuItem     *menuitem,
   if (ui.cur_mapping != 0) return;
   if (active == ui.ruler[0]) return;
   
+  end_text();
+  reset_focus();
   if (active && (ui.toolno[0]!=TOOL_PEN && ui.toolno[0]!=TOOL_HIGHLIGHTER)) {
     reset_selection();
     ui.toolno[0] = TOOL_PEN;
@@ -2015,6 +2239,8 @@ void
 on_optionsSavePreferences_activate     (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   save_config_to_file();
 }
 
@@ -2034,6 +2260,8 @@ on_helpAbout_activate                  (GtkMenuItem     *menuitem,
   GtkWidget *aboutDialog;
   GtkLabel *labelTitle;
   
+  end_text();
+  reset_focus();
   aboutDialog = create_aboutDialog ();
   labelTitle = GTK_LABEL(g_object_get_data(G_OBJECT(aboutDialog), "labelTitle"));
   gtk_label_set_markup(labelTitle, 
@@ -2047,6 +2275,12 @@ void
 on_buttonToolDefault_clicked           (GtkToolButton   *toolbutton,
                                         gpointer         user_data)
 {
+  if (ui.toolno[0]==TOOL_TEXT) {
+    on_toolsDefaultText_activate(NULL, NULL);
+    return;
+  }
+  end_text();
+  reset_focus();
   switch_mapping(0);
   if (ui.toolno[0] < NUM_STROKE_TOOLS) {
     g_memmove(&(ui.brushes[0][ui.toolno[0]]), ui.default_brushes+ui.toolno[0], sizeof(struct Brush));
@@ -2101,18 +2335,22 @@ on_canvas_button_press_event           (GtkWidget       *widget,
   GtkWidget *dialog;
   int mapping;
   gboolean is_core;
-
-  if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
-  if (event->button > 3) return FALSE; // no painting with the mouse wheel!
+  struct Item *item;
 
   is_core = (event->device == gdk_device_get_core_pointer());
   if (!ui.use_xinput && !is_core) return FALSE;
   if (ui.use_xinput && is_core && ui.discard_corepointer) return FALSE;
+  if (event->button > 3) return FALSE; // no painting with the mouse wheel!
   if (!is_core) { 
     // re-get the axis values since Synaptics sends bogus ones
     gdk_device_get_state(event->device, event->window, event->axes, NULL);
     fix_xinput_coords((GdkEvent *)event);
   }
+
+  if (ui.cur_item_type == ITEM_TEXT && !is_event_within_textview(event))
+    end_text();
+  if (ui.cur_item_type != ITEM_NONE) return FALSE; // we're already doing something
+
   ui.is_corestroke = is_core;
 
   if (ui.use_erasertip && event->device->source == GDK_SOURCE_ERASER)
@@ -2157,6 +2395,16 @@ on_canvas_button_press_event           (GtkWidget       *widget,
   ui.which_mouse_button = event->button;
   switch_mapping(mapping);
 
+  // in text tool, clicking in a text area edits it
+  if (ui.toolno[mapping] == TOOL_TEXT) {
+    item = click_is_in_text(ui.cur_layer, pt[0], pt[1]);
+    if (item!=NULL) { 
+      reset_selection();
+      start_text((GdkEvent *)event, item);
+      return FALSE;
+    }
+  }
+
   // if this can be a selection move, then it takes precedence over anything else  
   if (start_movesel((GdkEvent *)event)) return FALSE;
   
@@ -2184,6 +2432,9 @@ on_canvas_button_press_event           (GtkWidget       *widget,
   else if (ui.toolno[mapping] == TOOL_VERTSPACE) {
     start_vertspace((GdkEvent *)event);
   }
+  else if (ui.toolno[mapping] == TOOL_TEXT) {
+    start_text((GdkEvent *)event, NULL);
+  }
   return FALSE;
 }
 
@@ -2250,7 +2501,6 @@ on_canvas_key_press_event              (GtkWidget       *widget,
                                         GdkEventKey     *event,
                                         gpointer         user_data)
 {
-
   return FALSE;
 }
 
@@ -2321,7 +2571,8 @@ on_comboLayer_changed                  (GtkComboBox     *combobox,
 
   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
 
-  gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop focus on us
+  end_text();
+  reset_focus();
 
   val = gtk_combo_box_get_active(combobox);
   if (val == -1) return;
@@ -2349,6 +2600,8 @@ on_winMain_delete_event                (GtkWidget       *widget,
                                         GdkEvent        *event,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   if (ok_to_close()) gtk_main_quit();
   return TRUE;
 }
@@ -2358,8 +2611,12 @@ void
 on_optionsUseXInput_activate           (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   ui.allow_xinput = ui.use_xinput =
     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
+  gtk_widget_set_extension_events(GTK_WIDGET (canvas), 
+      ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
   update_mappings_menu();
 }
 
@@ -2390,7 +2647,11 @@ on_vscroll_changed                     (GtkAdjustment   *adjustment,
     ui.pageno--;
     tmppage = g_list_nth_data(journal.pages, ui.pageno);
   }
-  if (need_update) do_switch_page(ui.pageno, FALSE, FALSE);
+  if (need_update) {
+    end_text();
+    do_switch_page(ui.pageno, FALSE, FALSE);
+  }
+  reset_focus();
   return;
 }
 
@@ -2401,8 +2662,9 @@ on_spinPageNo_value_changed            (GtkSpinButton   *spinbutton,
   int val;
 
   if (ui.in_update_page_stuff) return; // avoid a bad retroaction
-
-  gtk_widget_grab_focus(GTK_WIDGET(canvas)); // stop blink-blink text cursor
+  
+  end_text();
+  reset_focus();
 
   val = gtk_spin_button_get_value_as_int(spinbutton) - 1;
 
@@ -2426,6 +2688,8 @@ on_journalDefaultBackground_activate   (GtkMenuItem     *menuitem,
   struct Page *pg;
   GList *pglist;
   
+  end_text();
+  reset_focus();
   reset_selection();
   
   pg = ui.cur_page;
@@ -2461,6 +2725,8 @@ on_journalSetAsDefault_activate        (GtkMenuItem     *menuitem,
 {
   if (ui.cur_page->bg->type != BG_SOLID) return;
   
+  end_text();
+  reset_focus();
   prepare_new_undo();
   undo->type = ITEM_NEW_DEFAULT_BG;
   undo->val_x = ui.default_page.width;
@@ -2594,6 +2860,8 @@ on_viewFullscreen_activate             (GtkMenuItem     *menuitem,
     active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem));
 
   if (active == ui.fullscreen) return;
+  end_text();
+  reset_focus();
   ui.fullscreen = active;
   gtk_check_menu_item_set_active(
     GTK_CHECK_MENU_ITEM(GET_COMPONENT("viewFullscreen")), ui.fullscreen);
@@ -2611,6 +2879,8 @@ void
 on_optionsButtonMappings_activate      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   ui.use_erasertip =
     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
   update_mappings_menu();
@@ -2625,6 +2895,8 @@ on_optionsAntialiasBG_activate         (GtkMenuItem     *menuitem,
   
   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
   if (ui.antialias_bg == active) return;
+  end_text();
+  reset_focus();
   ui.antialias_bg = active;
   rescale_bg_pixmaps();
 } 
@@ -2638,6 +2910,8 @@ on_optionsProgressiveBG_activate       (GtkMenuItem     *menuitem,
   
   active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
   if (ui.progressive_bg == active) return;
+  end_text();
+  reset_focus();
   ui.progressive_bg = active;
   if (!ui.progressive_bg) rescale_bg_pixmaps();
 }
@@ -2651,6 +2925,8 @@ on_mru_activate                        (GtkMenuItem     *menuitem,
   gboolean success;
   GtkWidget *dialog;
   
+  end_text();
+  reset_focus();
   if (!ok_to_close()) return; // user aborted on save confirmation
   
   for (which = 0 ; which < MRU_SIZE; which++) {
@@ -2700,7 +2976,7 @@ void
 on_button2Text_activate                (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-
+  process_mapping_activate(menuitem, 1, TOOL_TEXT);
 }
 
 
@@ -2735,6 +3011,8 @@ on_button2LinkBrush_activate           (GtkMenuItem     *menuitem,
   int i;
   
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
+  end_text();
+  reset_focus();
   ui.linked_brush[1] = BRUSH_LINKED;
   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
 }
@@ -2745,6 +3023,8 @@ on_button2CopyBrush_activate           (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
+  end_text();
+  reset_focus();
   if (ui.toolno[1] >= NUM_STROKE_TOOLS) {
     ui.linked_brush[1] = BRUSH_STATIC;
     update_mappings_menu_linkings();
@@ -2786,7 +3066,7 @@ void
 on_button3Text_activate                (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-
+  process_mapping_activate(menuitem, 2, TOOL_TEXT);
 }
 
 
@@ -2821,6 +3101,8 @@ on_button3LinkBrush_activate           (GtkMenuItem     *menuitem,
   int i;
   
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
+  end_text();
+  reset_focus();
   ui.linked_brush[2] = BRUSH_LINKED;
   for (i=0;i<NUM_STROKE_TOOLS;i++) update_mapping_linkings(i);
 }
@@ -2831,6 +3113,8 @@ on_button3CopyBrush_activate           (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
+  end_text();
+  reset_focus();
   if (ui.toolno[2] >= NUM_STROKE_TOOLS) {
     ui.linked_brush[2] = BRUSH_STATIC;
     update_mappings_menu_linkings();
@@ -2856,6 +3140,8 @@ on_viewSetZoom_activate                (GtkMenuItem     *menuitem,
   double test_w, test_h;
   GtkSpinButton *spinZoom;
   
+  end_text();
+  reset_focus();
   zoom_dialog = create_zoomDialog();
   zoom_percent = 100*ui.zoom / DEFAULT_ZOOM;
   spinZoom = GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(zoom_dialog), "spinZoom"));
@@ -2881,6 +3167,7 @@ on_viewSetZoom_activate                (GtkMenuItem     *menuitem,
     if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
       ui.zoom = DEFAULT_ZOOM*zoom_percent/100;
       gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+      rescale_text_items();
       rescale_bg_pixmaps();
     }
   } while (response == GTK_RESPONSE_APPLY);
@@ -2963,6 +3250,8 @@ on_toolsHand_activate                  (GtkMenuItem     *menuitem,
   if (ui.cur_mapping != 0) return;
   if (ui.toolno[0] == TOOL_HAND) return;
 
+  end_text();
+  reset_focus();
   reset_selection();
   ui.toolno[0] = TOOL_HAND;
   ui.ruler[0] = FALSE;
@@ -2994,6 +3283,8 @@ void
 on_optionsPrintRuling_activate         (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   ui.print_ruling = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
 }
 
@@ -3001,7 +3292,20 @@ void
 on_optionsDiscardCore_activate         (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+  end_text();
+  reset_focus();
   ui.discard_corepointer =
     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
   update_mappings_menu();
 }
+
+void
+on_fontButton_font_set                 (GtkFontButton   *fontbutton,
+                                        gpointer         user_data)
+{
+  gchar *str;
+  
+  str = g_strdup(gtk_font_button_get_font_name(fontbutton));
+  process_font_sel(str);
+}
+
index d7754ccbecb58ebb1923361e88c97a906fb5ad39..eb7b58fba62d91da50ac2f113d7f107cf041a1d2 100644 (file)
@@ -600,3 +600,11 @@ on_optionsPrintRuling_activate         (GtkMenuItem     *menuitem,
 void
 on_optionsDiscardCore_activate         (GtkMenuItem     *menuitem,
                                         gpointer         user_data);
+
+void
+on_fontButton_font_set                 (GtkFontButton   *fontbutton,
+                                        gpointer         user_data);
+
+void
+on_toggletoolClicked                   (GtkToolButton   *toolbutton,
+                                        gpointer         user_data);
index ba2fad0f3b6390e821a6ebe5b88804fdada6e7c8..91044b0e491202286720fd52005ed4b7682448d0 100644 (file)
@@ -21,8 +21,9 @@
 #include "xo-callbacks.h"
 #include "xo-misc.h"
 #include "xo-file.h"
+#include "xo-paint.h"
 
-const char *tool_names[NUM_TOOLS] = {"pen", "eraser", "highlighter", "", "", "selectrect", "vertspace", "hand"};
+const char *tool_names[NUM_TOOLS] = {"pen", "eraser", "highlighter", "text", "", "selectrect", "vertspace", "hand"};
 const char *color_names[COLOR_MAX] = {"black", "blue", "red", "green",
    "gray", "lightblue", "lightgreen", "magenta", "orange", "yellow", "white"};
 const char *bgtype_names[3] = {"solid", "pixmap", "pdf"};
@@ -73,7 +74,7 @@ gboolean save_journal(const char *filename)
   struct Layer *layer;
   struct Item *item;
   int i, is_clone;
-  char *tmpfn;
+  char *tmpfn, *tmpstr;
   gchar *pdfbuf;
   gsize pdflen;
   gboolean success;
@@ -88,8 +89,8 @@ gboolean save_journal(const char *filename)
   setlocale(LC_NUMERIC, "C");
   
   gzprintf(f, "<?xml version=\"1.0\" standalone=\"no\"?>\n"
-     "<title>Xournal document - see http://math.mit.edu/~auroux/software/xournal/</title>\n"
-     "<xournal version=\"" VERSION "\"/>\n");
+     "<xournal version=\"" VERSION "\">\n"
+     "<title>Xournal document - see http://math.mit.edu/~auroux/software/xournal/</title>\n");
   for (pagelist = journal.pages; pagelist!=NULL; pagelist = pagelist->next) {
     pg = (struct Page *)pagelist->data;
     gzprintf(f, "<page width=\"%.2f\" height=\"%.2f\">\n", pg->width, pg->height);
@@ -178,11 +179,24 @@ gboolean save_journal(const char *filename)
             gzprintf(f, "%.2f ", item->path->coords[i]);
           gzprintf(f, "\n</stroke>\n");
         }
+        if (item->type == ITEM_TEXT) {
+          gzprintf(f, "<text font=\"%s\" size=\"%.2f\" x=\"%.2f\" y=\"%.2f\" color=\"",
+            item->font_name, item->font_size, item->bbox.left, item->bbox.top);
+          if (item->brush.color_no >= 0)
+            gzputs(f, color_names[item->brush.color_no]);
+          else
+            gzprintf(f, "#%08x", item->brush.color_rgba);
+          tmpstr = g_markup_escape_text(item->text, -1);
+          gzprintf(f, "\">%s</text>\n", tmpstr);
+          g_free(tmpstr);
+          
+        }
       }
       gzprintf(f, "</layer>\n");
     }
     gzprintf(f, "</page>\n");
   }
+  gzprintf(f, "</xournal>\n");
   gzclose(f);
   setlocale(LC_NUMERIC, "");
 
@@ -471,9 +485,69 @@ void xoj_parser_start_element(GMarkupParseContext *context,
     tmpItem->brush.tool_options = 0;  // who cares ?
     if (tmpItem->brush.tool_type == TOOL_HIGHLIGHTER) {
       if (tmpItem->brush.color_no >= 0)
-        tmpItem->brush.color_rgba &= HILITER_ALPHA_MASK;
+        tmpItem->brush.color_rgba &= ui.hiliter_alpha_mask;
     }
   }
+  else if (!strcmp(element_name, "text")) { // start of a text item
+    if (tmpLayer == NULL || tmpItem != NULL) {
+      *error = xoj_invalid();
+      return;
+    }
+    tmpItem = (struct Item *)g_malloc0(sizeof(struct Item));
+    tmpItem->type = ITEM_TEXT;
+    tmpItem->canvas_item = NULL;
+    tmpLayer->items = g_list_append(tmpLayer->items, tmpItem);
+    tmpLayer->nitems++;
+    // scan for font, size, x, y, and color attributes
+    has_attr = 0;
+    while (*attribute_names!=NULL) {
+      if (!strcmp(*attribute_names, "font")) {
+        if (has_attr & 1) *error = xoj_invalid();
+        tmpItem->font_name = g_strdup(*attribute_values);
+        has_attr |= 1;
+      }
+      else if (!strcmp(*attribute_names, "size")) {
+        if (has_attr & 2) *error = xoj_invalid();
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpItem->font_size = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+        has_attr |= 2;
+      }
+      else if (!strcmp(*attribute_names, "x")) {
+        if (has_attr & 4) *error = xoj_invalid();
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpItem->bbox.left = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+        has_attr |= 4;
+      }
+      else if (!strcmp(*attribute_names, "y")) {
+        if (has_attr & 8) *error = xoj_invalid();
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpItem->bbox.top = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+        has_attr |= 8;
+      }
+      else if (!strcmp(*attribute_names, "color")) {
+        if (has_attr & 16) *error = xoj_invalid();
+        tmpItem->brush.color_no = COLOR_OTHER;
+        for (i=0; i<COLOR_MAX; i++)
+          if (!strcmp(*attribute_values, color_names[i])) {
+            tmpItem->brush.color_no = i;
+            tmpItem->brush.color_rgba = predef_colors_rgba[i];
+          }
+        // there's also the case of hex (#rrggbbaa) colors
+        if (tmpItem->brush.color_no == COLOR_OTHER && **attribute_values == '#') {
+          tmpItem->brush.color_rgba = strtol(*attribute_values + 1, &ptr, 16);
+          if (*ptr!=0) *error = xoj_invalid();
+        }
+        has_attr |= 16;
+      }
+      else *error = xoj_invalid();
+      attribute_names++;
+      attribute_values++;
+    }
+    if (has_attr!=31) *error = xoj_invalid();
+  }
 }
 
 void xoj_parser_end_element(GMarkupParseContext *context,
@@ -502,6 +576,13 @@ void xoj_parser_end_element(GMarkupParseContext *context,
     update_item_bbox(tmpItem);
     tmpItem = NULL;
   }
+  if (!strcmp(element_name, "text")) {
+    if (tmpItem == NULL) {
+      *error = xoj_invalid();
+      return;
+    }
+    tmpItem = NULL;
+  }
 }
 
 void xoj_parser_text(GMarkupParseContext *context,
@@ -528,6 +609,11 @@ void xoj_parser_text(GMarkupParseContext *context,
     tmpItem->path = gnome_canvas_points_new(n/2);
     g_memmove(tmpItem->path->coords, ui.cur_path.coords, n*sizeof(double));
   }
+  if (!strcmp(element_name, "text")) {
+    tmpItem->text = g_malloc(text_len+1);
+    g_memmove(tmpItem->text, text, text_len);
+    tmpItem->text[text_len]=0;
+  }
 }
 
 gboolean user_wants_second_chance(char **filename)
@@ -711,8 +797,9 @@ GList *attempt_load_gv_bg(char *filename)
   char *pipename;
   int buflen, remnlen, file_pageno;
   
-  buf = g_malloc(BUFSIZE); // a reasonable buffer size
   f = fopen(filename, "r");
+  if (f == NULL) return NULL;
+  buf = g_malloc(BUFSIZE); // a reasonable buffer size
   if (fread(buf, 1, 4, f) !=4 ||
         (strncmp((char *)buf, "%!PS", 4) && strncmp((char *)buf, "%PDF", 4))) {
     fclose(f);
@@ -1165,11 +1252,14 @@ void update_mru_menu(void)
 {
   int i;
   gboolean anyone = FALSE;
+  gchar *tmp;
   
   for (i=0; i<MRU_SIZE; i++) {
     if (ui.mru[i]!=NULL) {
-      gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(ui.mrumenu[i]))),
-          g_basename(ui.mru[i]));
+      tmp = g_strdup_printf("_%d %s", i+1, g_basename(ui.mru[i]));
+      gtk_label_set_text_with_mnemonic(GTK_LABEL(gtk_bin_get_child(GTK_BIN(ui.mrumenu[i]))),
+          tmp);
+      g_free(tmp);
       gtk_widget_show(ui.mrumenu[i]);
       anyone = TRUE;
     }
@@ -1231,7 +1321,7 @@ void init_config_default(void)
   ui.default_page.bg->ruling = RULING_LINED;
   ui.view_continuous = TRUE;
   ui.allow_xinput = TRUE;
-  ui.discard_corepointer = TRUE;
+  ui.discard_corepointer = FALSE;
   ui.bg_apply_all_pages = FALSE;
   ui.use_erasertip = FALSE;
   ui.window_default_width = 720;
@@ -1246,6 +1336,8 @@ void init_config_default(void)
   ui.print_ruling = TRUE;
   ui.default_unit = UNIT_CM;
   ui.default_path = NULL;
+  ui.default_font_name = g_strdup(DEFAULT_FONT);
+  ui.default_font_size = DEFAULT_FONT_SIZE;
   
   // the default UI vertical order
   ui.vertical_order[0][0] = 1; 
@@ -1280,6 +1372,8 @@ void init_config_default(void)
   // predef_thickness is already initialized as a global variable
   GS_BITMAP_DPI = 144;
   PDFTOPPM_PRINTING_DPI = 150;
+  
+  ui.hiliter_opacity = 0.5;
 }
 
 #if GLIB_CHECK_VERSION(2,6,0)
@@ -1376,6 +1470,9 @@ void save_config_to_file(void)
   update_keyval("general", "interface_fullscreen",
     " interface components in fullscreen mode, from top to bottom",
     verbose_vertical_order(ui.vertical_order[1]));
+  update_keyval("general", "highlighter_opacity",
+    " highlighter opacity (0 to 1, default 0.5)\n warning: opacity level is not saved in xoj files!",
+    g_strdup_printf("%.2f", ui.hiliter_opacity));
 
   update_keyval("paper", "width",
     " the default page width, in points (1/72 in)",
@@ -1436,7 +1533,7 @@ void save_config_to_file(void)
     " default highlighter thickness (fine = 1, medium = 2, thick = 3)",
     g_strdup_printf("%d", ui.default_brushes[TOOL_HIGHLIGHTER].thickness_no));
   update_keyval("tools", "btn2_tool",
-    " button 2 tool (pen, eraser, highlighter, selectrect, vertspace, hand)",
+    " button 2 tool (pen, eraser, highlighter, text, selectrect, vertspace, hand)",
     g_strdup(tool_names[ui.toolno[1]]));
   update_keyval("tools", "btn2_linked",
     " button 2 brush linked to primary brush (true/false) (overrides all other settings)",
@@ -1456,7 +1553,7 @@ void save_config_to_file(void)
     " button 2 eraser mode (eraser only)",
     g_strdup_printf("%d", ui.brushes[1][TOOL_ERASER].tool_options));
   update_keyval("tools", "btn3_tool",
-    " button 3 tool (pen, eraser, highlighter, selectrect, vertspace, hand)",
+    " button 3 tool (pen, eraser, highlighter, text, selectrect, vertspace, hand)",
     g_strdup(tool_names[ui.toolno[2]]));
   update_keyval("tools", "btn3_linked",
     " button 3 brush linked to primary brush (true/false) (overrides all other settings)",
@@ -1492,8 +1589,12 @@ void save_config_to_file(void)
     g_strdup_printf("%.2f;%.2f;%.2f", 
       predef_thickness[TOOL_HIGHLIGHTER][1], predef_thickness[TOOL_HIGHLIGHTER][2],
       predef_thickness[TOOL_HIGHLIGHTER][3]));
-  // set comments for keys / groups that don't exist
-  // set keyvals to current options
+  update_keyval("tools", "default_font",
+    " name of the default font",
+    g_strdup(ui.default_font_name));
+  update_keyval("tools", "default_font_size",
+    " default font size",
+    g_strdup_printf("%.1f", ui.default_font_size));
 
   buf = g_key_file_to_data(ui.config_data, NULL, NULL);
   if (buf == NULL) return;
@@ -1637,6 +1738,7 @@ void load_config_from_file(void)
   double f;
   gboolean b;
   int i, j;
+  gchar *str;
   
 #if GLIB_CHECK_VERSION(2,6,0)
   // no support for keyval files before Glib 2.6.0
@@ -1673,6 +1775,7 @@ void load_config_from_file(void)
   parse_keyval_string("general", "default_path", &ui.default_path);
   parse_keyval_vorderlist("general", "interface_order", ui.vertical_order[0]);
   parse_keyval_vorderlist("general", "interface_fullscreen", ui.vertical_order[1]);
+  parse_keyval_float("general", "highlighter_opacity", &ui.hiliter_opacity, 0., 1.);
   
   parse_keyval_float("paper", "width", &ui.default_page.width, 1., 5000.);
   parse_keyval_float("paper", "height", &ui.default_page.height, 1., 5000.);
@@ -1735,5 +1838,8 @@ void load_config_from_file(void)
   parse_keyval_floatlist("tools", "pen_thicknesses", predef_thickness[TOOL_PEN], 5, 0.01, 1000.0);
   parse_keyval_floatlist("tools", "eraser_thicknesses", predef_thickness[TOOL_ERASER]+1, 3, 0.01, 1000.0);
   parse_keyval_floatlist("tools", "highlighter_thicknesses", predef_thickness[TOOL_HIGHLIGHTER]+1, 3, 0.01, 1000.0);
+  if (parse_keyval_string("tools", "default_font", &str))
+    if (str!=NULL) { g_free(ui.default_font_name); ui.default_font_name = str; }
+  parse_keyval_float("tools", "default_font_size", &ui.default_font_size, 1., 200.);
 #endif
 }
index 00114f5d9ec15706334121e3a94461f93de5ba59..163118981ca18f72e0896c6fe486a4d5767b722d 100644 (file)
@@ -317,6 +317,10 @@ create_winMain (void)
   GtkWidget *buttonYellow;
   GtkWidget *buttonWhite;
   GtkWidget *buttonColorOther;
+  GtkWidget *toolitem21;
+  GtkWidget *vseparator10;
+  GtkWidget *toolitem20;
+  GtkWidget *fontButton;
   GtkWidget *scrolledwindowMain;
   GtkWidget *hbox1;
   GtkWidget *labelPage;
@@ -356,7 +360,7 @@ create_winMain (void)
   gtk_widget_show (fileNew);
   gtk_container_add (GTK_CONTAINER (menuFile_menu), fileNew);
 
-  fileNewBackground = gtk_image_menu_item_new_with_mnemonic ("Annotate PDF");
+  fileNewBackground = gtk_image_menu_item_new_with_mnemonic ("Annotate PD_F");
   gtk_widget_show (fileNewBackground);
   gtk_container_add (GTK_CONTAINER (menuFile_menu), fileNewBackground);
 
@@ -381,7 +385,7 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuFile_menu), separator1);
   gtk_widget_set_sensitive (separator1, FALSE);
 
-  fileRecentFiles = gtk_menu_item_new_with_mnemonic ("Recent Files");
+  fileRecentFiles = gtk_menu_item_new_with_mnemonic ("Recent Doc_uments");
   gtk_widget_show (fileRecentFiles);
   gtk_container_add (GTK_CONTAINER (menuFile_menu), fileRecentFiles);
 
@@ -436,10 +440,16 @@ create_winMain (void)
   filePrint = gtk_image_menu_item_new_from_stock ("gtk-print", accel_group);
   gtk_widget_show (filePrint);
   gtk_container_add (GTK_CONTAINER (menuFile_menu), filePrint);
+  gtk_widget_add_accelerator (filePrint, "activate", accel_group,
+                              GDK_P, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
-  filePrintPDF = gtk_menu_item_new_with_mnemonic ("Export to PDF");
+  filePrintPDF = gtk_menu_item_new_with_mnemonic ("_Export to PDF");
   gtk_widget_show (filePrintPDF);
   gtk_container_add (GTK_CONTAINER (menuFile_menu), filePrintPDF);
+  gtk_widget_add_accelerator (filePrintPDF, "activate", accel_group,
+                              GDK_E, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   separator2 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator2);
@@ -460,10 +470,16 @@ create_winMain (void)
   editUndo = gtk_image_menu_item_new_from_stock ("gtk-undo", accel_group);
   gtk_widget_show (editUndo);
   gtk_container_add (GTK_CONTAINER (menuEdit_menu), editUndo);
+  gtk_widget_add_accelerator (editUndo, "activate", accel_group,
+                              GDK_Z, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   editRedo = gtk_image_menu_item_new_from_stock ("gtk-redo", accel_group);
   gtk_widget_show (editRedo);
   gtk_container_add (GTK_CONTAINER (menuEdit_menu), editRedo);
+  gtk_widget_add_accelerator (editRedo, "activate", accel_group,
+                              GDK_Y, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   separator3 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator3);
@@ -485,6 +501,9 @@ create_winMain (void)
   editDelete = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group);
   gtk_widget_show (editDelete);
   gtk_container_add (GTK_CONTAINER (menuEdit_menu), editDelete);
+  gtk_widget_add_accelerator (editDelete, "activate", accel_group,
+                              GDK_Delete, (GdkModifierType) 0,
+                              GTK_ACCEL_VISIBLE);
 
   menuView = gtk_menu_item_new_with_mnemonic ("_View");
   gtk_widget_show (menuView);
@@ -493,13 +512,13 @@ create_winMain (void)
   menuView_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuView), menuView_menu);
 
-  viewContinuous = gtk_radio_menu_item_new_with_mnemonic (viewContinuous_group, "Continuous");
+  viewContinuous = gtk_radio_menu_item_new_with_mnemonic (viewContinuous_group, "_Continuous");
   viewContinuous_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (viewContinuous));
   gtk_widget_show (viewContinuous);
   gtk_container_add (GTK_CONTAINER (menuView_menu), viewContinuous);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (viewContinuous), TRUE);
 
-  viewOnePage = gtk_radio_menu_item_new_with_mnemonic (viewContinuous_group, "One Page");
+  viewOnePage = gtk_radio_menu_item_new_with_mnemonic (viewContinuous_group, "_One Page");
   viewContinuous_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (viewOnePage));
   gtk_widget_show (viewOnePage);
   gtk_container_add (GTK_CONTAINER (menuView_menu), viewOnePage);
@@ -513,6 +532,9 @@ create_winMain (void)
   viewFullscreen = gtk_check_menu_item_new_with_mnemonic ("Full Screen");
   gtk_widget_show (viewFullscreen);
   gtk_container_add (GTK_CONTAINER (menuView_menu), viewFullscreen);
+  gtk_widget_add_accelerator (viewFullscreen, "activate", accel_group,
+                              GDK_F11, (GdkModifierType) 0,
+                              GTK_ACCEL_VISIBLE);
 
   separator4 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator4);
@@ -529,24 +551,36 @@ create_winMain (void)
   viewZoomIn = gtk_image_menu_item_new_from_stock ("gtk-zoom-in", accel_group);
   gtk_widget_show (viewZoomIn);
   gtk_container_add (GTK_CONTAINER (menuViewZoom_menu), viewZoomIn);
+  gtk_widget_add_accelerator (viewZoomIn, "activate", accel_group,
+                              GDK_plus, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   viewZoomOut = gtk_image_menu_item_new_from_stock ("gtk-zoom-out", accel_group);
   gtk_widget_show (viewZoomOut);
   gtk_container_add (GTK_CONTAINER (menuViewZoom_menu), viewZoomOut);
+  gtk_widget_add_accelerator (viewZoomOut, "activate", accel_group,
+                              GDK_minus, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   viewNormalSize = gtk_image_menu_item_new_from_stock ("gtk-zoom-100", accel_group);
   gtk_widget_show (viewNormalSize);
   gtk_container_add (GTK_CONTAINER (menuViewZoom_menu), viewNormalSize);
+  gtk_widget_add_accelerator (viewNormalSize, "activate", accel_group,
+                              GDK_0, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
-  viewPageWidth = gtk_image_menu_item_new_with_mnemonic ("Page Width");
+  viewPageWidth = gtk_image_menu_item_new_with_mnemonic ("Page _Width");
   gtk_widget_show (viewPageWidth);
   gtk_container_add (GTK_CONTAINER (menuViewZoom_menu), viewPageWidth);
+  gtk_widget_add_accelerator (viewPageWidth, "activate", accel_group,
+                              GDK_equal, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   image625 = gtk_image_new_from_stock ("gtk-zoom-fit", GTK_ICON_SIZE_MENU);
   gtk_widget_show (image625);
   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewPageWidth), image625);
 
-  viewSetZoom = gtk_menu_item_new_with_mnemonic ("Set Zoom");
+  viewSetZoom = gtk_menu_item_new_with_mnemonic ("_Set Zoom");
   gtk_widget_show (viewSetZoom);
   gtk_container_add (GTK_CONTAINER (menuViewZoom_menu), viewSetZoom);
 
@@ -555,33 +589,45 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuView_menu), separator5);
   gtk_widget_set_sensitive (separator5, FALSE);
 
-  viewFirstPage = gtk_image_menu_item_new_with_mnemonic ("First Page");
+  viewFirstPage = gtk_image_menu_item_new_with_mnemonic ("_First Page");
   gtk_widget_show (viewFirstPage);
   gtk_container_add (GTK_CONTAINER (menuView_menu), viewFirstPage);
+  gtk_widget_add_accelerator (viewFirstPage, "activate", accel_group,
+                              GDK_Home, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   image626 = gtk_image_new_from_stock ("gtk-goto-first", GTK_ICON_SIZE_MENU);
   gtk_widget_show (image626);
   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewFirstPage), image626);
 
-  viewPreviousPage = gtk_image_menu_item_new_with_mnemonic ("Previous Page");
+  viewPreviousPage = gtk_image_menu_item_new_with_mnemonic ("_Previous Page");
   gtk_widget_show (viewPreviousPage);
   gtk_container_add (GTK_CONTAINER (menuView_menu), viewPreviousPage);
+  gtk_widget_add_accelerator (viewPreviousPage, "activate", accel_group,
+                              GDK_Left, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   image627 = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_MENU);
   gtk_widget_show (image627);
   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewPreviousPage), image627);
 
-  viewNextPage = gtk_image_menu_item_new_with_mnemonic ("Next Page");
+  viewNextPage = gtk_image_menu_item_new_with_mnemonic ("_Next Page");
   gtk_widget_show (viewNextPage);
   gtk_container_add (GTK_CONTAINER (menuView_menu), viewNextPage);
+  gtk_widget_add_accelerator (viewNextPage, "activate", accel_group,
+                              GDK_Right, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   image628 = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_MENU);
   gtk_widget_show (image628);
   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewNextPage), image628);
 
-  viewLastPage = gtk_image_menu_item_new_with_mnemonic ("Last Page");
+  viewLastPage = gtk_image_menu_item_new_with_mnemonic ("_Last Page");
   gtk_widget_show (viewLastPage);
   gtk_container_add (GTK_CONTAINER (menuView_menu), viewLastPage);
+  gtk_widget_add_accelerator (viewLastPage, "activate", accel_group,
+                              GDK_End, (GdkModifierType) GDK_CONTROL_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   image629 = gtk_image_new_from_stock ("gtk-goto-last", GTK_ICON_SIZE_MENU);
   gtk_widget_show (image629);
@@ -592,7 +638,7 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuView_menu), separator6);
   gtk_widget_set_sensitive (separator6, FALSE);
 
-  viewShowLayer = gtk_image_menu_item_new_with_mnemonic ("Show Layer");
+  viewShowLayer = gtk_image_menu_item_new_with_mnemonic ("_Show Layer");
   gtk_widget_show (viewShowLayer);
   gtk_container_add (GTK_CONTAINER (menuView_menu), viewShowLayer);
 
@@ -600,7 +646,7 @@ create_winMain (void)
   gtk_widget_show (image630);
   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewShowLayer), image630);
 
-  viewHideLayer = gtk_image_menu_item_new_with_mnemonic ("Hide Layer");
+  viewHideLayer = gtk_image_menu_item_new_with_mnemonic ("_Hide Layer");
   gtk_widget_show (viewHideLayer);
   gtk_container_add (GTK_CONTAINER (menuView_menu), viewHideLayer);
 
@@ -615,19 +661,19 @@ create_winMain (void)
   menuJournal_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuJournal), menuJournal_menu);
 
-  journalNewPageBefore = gtk_menu_item_new_with_mnemonic ("New Page Before");
+  journalNewPageBefore = gtk_menu_item_new_with_mnemonic ("New Page _Before");
   gtk_widget_show (journalNewPageBefore);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalNewPageBefore);
 
-  journalNewPageAfter = gtk_menu_item_new_with_mnemonic ("New Page After");
+  journalNewPageAfter = gtk_menu_item_new_with_mnemonic ("New Page _After");
   gtk_widget_show (journalNewPageAfter);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalNewPageAfter);
 
-  journalNewPageEnd = gtk_menu_item_new_with_mnemonic ("New Page At End");
+  journalNewPageEnd = gtk_menu_item_new_with_mnemonic ("New Page At _End");
   gtk_widget_show (journalNewPageEnd);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalNewPageEnd);
 
-  journalDeletePage = gtk_menu_item_new_with_mnemonic ("Delete Page");
+  journalDeletePage = gtk_menu_item_new_with_mnemonic ("_Delete Page");
   gtk_widget_show (journalDeletePage);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalDeletePage);
 
@@ -636,15 +682,15 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), separator7);
   gtk_widget_set_sensitive (separator7, FALSE);
 
-  journalNewLayer = gtk_menu_item_new_with_mnemonic ("New Layer");
+  journalNewLayer = gtk_menu_item_new_with_mnemonic ("_New Layer");
   gtk_widget_show (journalNewLayer);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalNewLayer);
 
-  journalDeleteLayer = gtk_menu_item_new_with_mnemonic ("Delete Layer");
+  journalDeleteLayer = gtk_menu_item_new_with_mnemonic ("Delete La_yer");
   gtk_widget_show (journalDeleteLayer);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalDeleteLayer);
 
-  journalFlatten = gtk_menu_item_new_with_mnemonic ("Flatten");
+  journalFlatten = gtk_menu_item_new_with_mnemonic ("_Flatten");
   gtk_widget_show (journalFlatten);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalFlatten);
 
@@ -653,48 +699,48 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), separator8);
   gtk_widget_set_sensitive (separator8, FALSE);
 
-  journalPaperSize = gtk_menu_item_new_with_mnemonic ("Paper Size");
+  journalPaperSize = gtk_menu_item_new_with_mnemonic ("Paper Si_ze");
   gtk_widget_show (journalPaperSize);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalPaperSize);
 
-  journalPaperColor = gtk_menu_item_new_with_mnemonic ("Paper Color");
+  journalPaperColor = gtk_menu_item_new_with_mnemonic ("Paper _Color");
   gtk_widget_show (journalPaperColor);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalPaperColor);
 
   journalPaperColor_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (journalPaperColor), journalPaperColor_menu);
 
-  papercolorWhite = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "white paper");
+  papercolorWhite = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "_white paper");
   papercolorWhite_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (papercolorWhite));
   gtk_widget_show (papercolorWhite);
   gtk_container_add (GTK_CONTAINER (journalPaperColor_menu), papercolorWhite);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (papercolorWhite), TRUE);
 
-  papercolorYellow = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "yellow paper");
+  papercolorYellow = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "_yellow paper");
   papercolorWhite_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (papercolorYellow));
   gtk_widget_show (papercolorYellow);
   gtk_container_add (GTK_CONTAINER (journalPaperColor_menu), papercolorYellow);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (papercolorYellow), TRUE);
 
-  papercolorPink = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "pink paper");
+  papercolorPink = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "_pink paper");
   papercolorWhite_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (papercolorPink));
   gtk_widget_show (papercolorPink);
   gtk_container_add (GTK_CONTAINER (journalPaperColor_menu), papercolorPink);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (papercolorPink), TRUE);
 
-  papercolorOrange = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "orange paper");
+  papercolorOrange = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "_orange paper");
   papercolorWhite_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (papercolorOrange));
   gtk_widget_show (papercolorOrange);
   gtk_container_add (GTK_CONTAINER (journalPaperColor_menu), papercolorOrange);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (papercolorOrange), TRUE);
 
-  papercolorBlue = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "blue paper");
+  papercolorBlue = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "_blue paper");
   papercolorWhite_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (papercolorBlue));
   gtk_widget_show (papercolorBlue);
   gtk_container_add (GTK_CONTAINER (journalPaperColor_menu), papercolorBlue);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (papercolorBlue), TRUE);
 
-  papercolorGreen = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "green paper");
+  papercolorGreen = gtk_radio_menu_item_new_with_mnemonic (papercolorWhite_group, "_green paper");
   papercolorWhite_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (papercolorGreen));
   gtk_widget_show (papercolorGreen);
   gtk_container_add (GTK_CONTAINER (journalPaperColor_menu), papercolorGreen);
@@ -711,32 +757,32 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (journalPaperColor_menu), papercolorNA);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (papercolorNA), TRUE);
 
-  journalPaperStyle = gtk_menu_item_new_with_mnemonic ("Paper Style");
+  journalPaperStyle = gtk_menu_item_new_with_mnemonic ("Paper _Style");
   gtk_widget_show (journalPaperStyle);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalPaperStyle);
 
   journalPaperStyle_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (journalPaperStyle), journalPaperStyle_menu);
 
-  paperstylePlain = gtk_radio_menu_item_new_with_mnemonic (paperstylePlain_group, "plain");
+  paperstylePlain = gtk_radio_menu_item_new_with_mnemonic (paperstylePlain_group, "_plain");
   paperstylePlain_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (paperstylePlain));
   gtk_widget_show (paperstylePlain);
   gtk_container_add (GTK_CONTAINER (journalPaperStyle_menu), paperstylePlain);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (paperstylePlain), TRUE);
 
-  paperstyleLined = gtk_radio_menu_item_new_with_mnemonic (paperstylePlain_group, "lined");
+  paperstyleLined = gtk_radio_menu_item_new_with_mnemonic (paperstylePlain_group, "_lined");
   paperstylePlain_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (paperstyleLined));
   gtk_widget_show (paperstyleLined);
   gtk_container_add (GTK_CONTAINER (journalPaperStyle_menu), paperstyleLined);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (paperstyleLined), TRUE);
 
-  paperstyleRuled = gtk_radio_menu_item_new_with_mnemonic (paperstylePlain_group, "ruled");
+  paperstyleRuled = gtk_radio_menu_item_new_with_mnemonic (paperstylePlain_group, "_ruled");
   paperstylePlain_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (paperstyleRuled));
   gtk_widget_show (paperstyleRuled);
   gtk_container_add (GTK_CONTAINER (journalPaperStyle_menu), paperstyleRuled);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (paperstyleRuled), TRUE);
 
-  paperstyleGraph = gtk_radio_menu_item_new_with_mnemonic (paperstylePlain_group, "graph");
+  paperstyleGraph = gtk_radio_menu_item_new_with_mnemonic (paperstylePlain_group, "_graph");
   paperstylePlain_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (paperstyleGraph));
   gtk_widget_show (paperstyleGraph);
   gtk_container_add (GTK_CONTAINER (journalPaperStyle_menu), paperstyleGraph);
@@ -747,7 +793,7 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (journalPaperStyle_menu), paperstyleNA);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (paperstyleNA), TRUE);
 
-  journalApplyAllPages = gtk_check_menu_item_new_with_mnemonic ("Apply To All Pages");
+  journalApplyAllPages = gtk_check_menu_item_new_with_mnemonic ("Apply _To All Pages");
   gtk_widget_show (journalApplyAllPages);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalApplyAllPages);
 
@@ -756,7 +802,7 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), separator23);
   gtk_widget_set_sensitive (separator23, FALSE);
 
-  journalLoadBackground = gtk_image_menu_item_new_with_mnemonic ("Load Background");
+  journalLoadBackground = gtk_image_menu_item_new_with_mnemonic ("_Load Background");
   gtk_widget_show (journalLoadBackground);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalLoadBackground);
 
@@ -764,7 +810,7 @@ create_winMain (void)
   gtk_widget_show (image632);
   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (journalLoadBackground), image632);
 
-  journalScreenshot = gtk_menu_item_new_with_mnemonic ("Background Screenshot");
+  journalScreenshot = gtk_menu_item_new_with_mnemonic ("Background Screens_hot");
   gtk_widget_show (journalScreenshot);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalScreenshot);
 
@@ -773,11 +819,11 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), separator19);
   gtk_widget_set_sensitive (separator19, FALSE);
 
-  journalDefaultBackground = gtk_menu_item_new_with_mnemonic ("Default Paper");
+  journalDefaultBackground = gtk_menu_item_new_with_mnemonic ("Default _Paper");
   gtk_widget_show (journalDefaultBackground);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalDefaultBackground);
 
-  journalSetAsDefault = gtk_menu_item_new_with_mnemonic ("Set As Default");
+  journalSetAsDefault = gtk_menu_item_new_with_mnemonic ("Set As De_fault");
   gtk_widget_show (journalSetAsDefault);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalSetAsDefault);
 
@@ -792,24 +838,36 @@ create_winMain (void)
   toolsPen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (toolsPen));
   gtk_widget_show (toolsPen);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsPen);
+  gtk_widget_add_accelerator (toolsPen, "activate", accel_group,
+                              GDK_P, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsPen), TRUE);
 
   toolsEraser = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "_Eraser");
   toolsPen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (toolsEraser));
   gtk_widget_show (toolsEraser);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsEraser);
+  gtk_widget_add_accelerator (toolsEraser, "activate", accel_group,
+                              GDK_E, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsEraser), TRUE);
 
   toolsHighlighter = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "_Highlighter");
   toolsPen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (toolsHighlighter));
   gtk_widget_show (toolsHighlighter);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsHighlighter);
+  gtk_widget_add_accelerator (toolsHighlighter, "activate", accel_group,
+                              GDK_H, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsHighlighter), TRUE);
 
   toolsText = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "_Text");
   toolsPen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (toolsText));
   gtk_widget_show (toolsText);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsText);
+  gtk_widget_add_accelerator (toolsText, "activate", accel_group,
+                              GDK_T, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsText), TRUE);
 
   separator9 = gtk_separator_menu_item_new ();
@@ -817,28 +875,40 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuTools_menu), separator9);
   gtk_widget_set_sensitive (separator9, FALSE);
 
-  toolsSelectRegion = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "_Select Region");
+  toolsSelectRegion = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "Select Re_gion");
   toolsPen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (toolsSelectRegion));
   gtk_widget_show (toolsSelectRegion);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsSelectRegion);
+  gtk_widget_add_accelerator (toolsSelectRegion, "activate", accel_group,
+                              GDK_G, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsSelectRegion), TRUE);
 
-  toolsSelectRectangle = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "Select Rectangle");
+  toolsSelectRectangle = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "Select _Rectangle");
   toolsPen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (toolsSelectRectangle));
   gtk_widget_show (toolsSelectRectangle);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsSelectRectangle);
+  gtk_widget_add_accelerator (toolsSelectRectangle, "activate", accel_group,
+                              GDK_R, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsSelectRectangle), TRUE);
 
-  toolsVerticalSpace = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "Vertical Space");
+  toolsVerticalSpace = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "_Vertical Space");
   toolsPen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (toolsVerticalSpace));
   gtk_widget_show (toolsVerticalSpace);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsVerticalSpace);
+  gtk_widget_add_accelerator (toolsVerticalSpace, "activate", accel_group,
+                              GDK_V, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsVerticalSpace), TRUE);
 
-  toolsHand = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "Hand Tool");
+  toolsHand = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, "H_and Tool");
   toolsPen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (toolsHand));
   gtk_widget_show (toolsHand);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsHand);
+  gtk_widget_add_accelerator (toolsHand, "activate", accel_group,
+                              GDK_A, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   separator16 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator16);
@@ -856,31 +926,31 @@ create_winMain (void)
   toolsColor_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (toolsColor), toolsColor_menu);
 
-  colorBlack = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "black");
+  colorBlack = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "blac_k");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorBlack));
   gtk_widget_show (colorBlack);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorBlack);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (colorBlack), TRUE);
 
-  colorBlue = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "blue");
+  colorBlue = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "_blue");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorBlue));
   gtk_widget_show (colorBlue);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorBlue);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (colorBlue), TRUE);
 
-  colorRed = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "red");
+  colorRed = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "_red");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorRed));
   gtk_widget_show (colorRed);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorRed);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (colorRed), TRUE);
 
-  colorGreen = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "green");
+  colorGreen = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "_green");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorGreen));
   gtk_widget_show (colorGreen);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorGreen);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (colorGreen), TRUE);
 
-  colorGray = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "gray");
+  colorGray = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "gr_ay");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorGray));
   gtk_widget_show (colorGray);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorGray);
@@ -891,37 +961,37 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), separator17);
   gtk_widget_set_sensitive (separator17, FALSE);
 
-  colorLightBlue = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "light blue");
+  colorLightBlue = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "light bl_ue");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorLightBlue));
   gtk_widget_show (colorLightBlue);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorLightBlue);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (colorLightBlue), TRUE);
 
-  colorLightGreen = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "light green");
+  colorLightGreen = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "light gr_een");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorLightGreen));
   gtk_widget_show (colorLightGreen);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorLightGreen);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (colorLightGreen), TRUE);
 
-  colorMagenta = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "magenta");
+  colorMagenta = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "_magenta");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorMagenta));
   gtk_widget_show (colorMagenta);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorMagenta);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (colorMagenta), TRUE);
 
-  colorOrange = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "orange");
+  colorOrange = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "_orange");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorOrange));
   gtk_widget_show (colorOrange);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorOrange);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (colorOrange), TRUE);
 
-  colorYellow = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "yellow");
+  colorYellow = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "_yellow");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorYellow));
   gtk_widget_show (colorYellow);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorYellow);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (colorYellow), TRUE);
 
-  colorWhite = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "white");
+  colorWhite = gtk_radio_menu_item_new_with_mnemonic (colorBlack_group, "_white");
   colorBlack_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (colorWhite));
   gtk_widget_show (colorWhite);
   gtk_container_add (GTK_CONTAINER (toolsColor_menu), colorWhite);
@@ -945,56 +1015,56 @@ create_winMain (void)
   toolsPenOptions_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (toolsPenOptions), toolsPenOptions_menu);
 
-  penthicknessVeryFine = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "very fine");
+  penthicknessVeryFine = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "_very fine");
   penthicknessVeryFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (penthicknessVeryFine));
   gtk_widget_show (penthicknessVeryFine);
   gtk_container_add (GTK_CONTAINER (toolsPenOptions_menu), penthicknessVeryFine);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (penthicknessVeryFine), TRUE);
 
-  penthicknessFine = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "fine");
+  penthicknessFine = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "_fine");
   penthicknessVeryFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (penthicknessFine));
   gtk_widget_show (penthicknessFine);
   gtk_container_add (GTK_CONTAINER (toolsPenOptions_menu), penthicknessFine);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (penthicknessFine), TRUE);
 
-  penthicknessMedium = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "medium");
+  penthicknessMedium = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "_medium");
   penthicknessVeryFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (penthicknessMedium));
   gtk_widget_show (penthicknessMedium);
   gtk_container_add (GTK_CONTAINER (toolsPenOptions_menu), penthicknessMedium);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (penthicknessMedium), TRUE);
 
-  penthicknessThick = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "thick");
+  penthicknessThick = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "_thick");
   penthicknessVeryFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (penthicknessThick));
   gtk_widget_show (penthicknessThick);
   gtk_container_add (GTK_CONTAINER (toolsPenOptions_menu), penthicknessThick);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (penthicknessThick), TRUE);
 
-  penthicknessVeryThick = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "very thick");
+  penthicknessVeryThick = gtk_radio_menu_item_new_with_mnemonic (penthicknessVeryFine_group, "ver_y thick");
   penthicknessVeryFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (penthicknessVeryThick));
   gtk_widget_show (penthicknessVeryThick);
   gtk_container_add (GTK_CONTAINER (toolsPenOptions_menu), penthicknessVeryThick);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (penthicknessVeryThick), TRUE);
 
-  toolsEraserOptions = gtk_menu_item_new_with_mnemonic ("Eraser Options");
+  toolsEraserOptions = gtk_menu_item_new_with_mnemonic ("Eraser Optio_ns");
   gtk_widget_show (toolsEraserOptions);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsEraserOptions);
 
   toolsEraserOptions_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (toolsEraserOptions), toolsEraserOptions_menu);
 
-  eraserFine = gtk_radio_menu_item_new_with_mnemonic (eraserFine_group, "fine");
+  eraserFine = gtk_radio_menu_item_new_with_mnemonic (eraserFine_group, "_fine");
   eraserFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (eraserFine));
   gtk_widget_show (eraserFine);
   gtk_container_add (GTK_CONTAINER (toolsEraserOptions_menu), eraserFine);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (eraserFine), TRUE);
 
-  eraserMedium = gtk_radio_menu_item_new_with_mnemonic (eraserFine_group, "medium");
+  eraserMedium = gtk_radio_menu_item_new_with_mnemonic (eraserFine_group, "_medium");
   eraserFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (eraserMedium));
   gtk_widget_show (eraserMedium);
   gtk_container_add (GTK_CONTAINER (toolsEraserOptions_menu), eraserMedium);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (eraserMedium), TRUE);
 
-  eraserThick = gtk_radio_menu_item_new_with_mnemonic (eraserFine_group, "thick");
+  eraserThick = gtk_radio_menu_item_new_with_mnemonic (eraserFine_group, "_thick");
   eraserFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (eraserThick));
   gtk_widget_show (eraserThick);
   gtk_container_add (GTK_CONTAINER (toolsEraserOptions_menu), eraserThick);
@@ -1005,52 +1075,55 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (toolsEraserOptions_menu), separator14);
   gtk_widget_set_sensitive (separator14, FALSE);
 
-  eraserStandard = gtk_radio_menu_item_new_with_mnemonic (eraserStandard_group, "standard");
+  eraserStandard = gtk_radio_menu_item_new_with_mnemonic (eraserStandard_group, "_standard");
   eraserStandard_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (eraserStandard));
   gtk_widget_show (eraserStandard);
   gtk_container_add (GTK_CONTAINER (toolsEraserOptions_menu), eraserStandard);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (eraserStandard), TRUE);
 
-  eraserWhiteout = gtk_radio_menu_item_new_with_mnemonic (eraserStandard_group, "whiteout");
+  eraserWhiteout = gtk_radio_menu_item_new_with_mnemonic (eraserStandard_group, "_whiteout");
   eraserStandard_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (eraserWhiteout));
   gtk_widget_show (eraserWhiteout);
   gtk_container_add (GTK_CONTAINER (toolsEraserOptions_menu), eraserWhiteout);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (eraserWhiteout), TRUE);
 
-  eraserDeleteStrokes = gtk_radio_menu_item_new_with_mnemonic (eraserStandard_group, "delete strokes");
+  eraserDeleteStrokes = gtk_radio_menu_item_new_with_mnemonic (eraserStandard_group, "_delete strokes");
   eraserStandard_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (eraserDeleteStrokes));
   gtk_widget_show (eraserDeleteStrokes);
   gtk_container_add (GTK_CONTAINER (toolsEraserOptions_menu), eraserDeleteStrokes);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (eraserDeleteStrokes), TRUE);
 
-  toolsHighlighterOptions = gtk_menu_item_new_with_mnemonic ("Highlighter Options");
+  toolsHighlighterOptions = gtk_menu_item_new_with_mnemonic ("Highlighter Opt_ions");
   gtk_widget_show (toolsHighlighterOptions);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsHighlighterOptions);
 
   toolsHighlighterOptions_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (toolsHighlighterOptions), toolsHighlighterOptions_menu);
 
-  highlighterFine = gtk_radio_menu_item_new_with_mnemonic (highlighterFine_group, "fine");
+  highlighterFine = gtk_radio_menu_item_new_with_mnemonic (highlighterFine_group, "_fine");
   highlighterFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (highlighterFine));
   gtk_widget_show (highlighterFine);
   gtk_container_add (GTK_CONTAINER (toolsHighlighterOptions_menu), highlighterFine);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (highlighterFine), TRUE);
 
-  highlighterMedium = gtk_radio_menu_item_new_with_mnemonic (highlighterFine_group, "medium");
+  highlighterMedium = gtk_radio_menu_item_new_with_mnemonic (highlighterFine_group, "_medium");
   highlighterFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (highlighterMedium));
   gtk_widget_show (highlighterMedium);
   gtk_container_add (GTK_CONTAINER (toolsHighlighterOptions_menu), highlighterMedium);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (highlighterMedium), TRUE);
 
-  highlighterThick = gtk_radio_menu_item_new_with_mnemonic (highlighterFine_group, "thick");
+  highlighterThick = gtk_radio_menu_item_new_with_mnemonic (highlighterFine_group, "_thick");
   highlighterFine_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (highlighterThick));
   gtk_widget_show (highlighterThick);
   gtk_container_add (GTK_CONTAINER (toolsHighlighterOptions_menu), highlighterThick);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (highlighterThick), TRUE);
 
-  toolsTextFont = gtk_image_menu_item_new_with_mnemonic ("Text Font");
+  toolsTextFont = gtk_image_menu_item_new_with_mnemonic ("Text _Font...");
   gtk_widget_show (toolsTextFont);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsTextFont);
+  gtk_widget_add_accelerator (toolsTextFont, "activate", accel_group,
+                              GDK_F, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   image634 = gtk_image_new_from_stock ("gtk-select-font", GTK_ICON_SIZE_MENU);
   gtk_widget_show (image634);
@@ -1061,7 +1134,7 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuTools_menu), separator10);
   gtk_widget_set_sensitive (separator10, FALSE);
 
-  toolsDefaultPen = gtk_menu_item_new_with_mnemonic ("Default Pen");
+  toolsDefaultPen = gtk_menu_item_new_with_mnemonic ("_Default Pen");
   gtk_widget_show (toolsDefaultPen);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsDefaultPen);
 
@@ -1073,11 +1146,11 @@ create_winMain (void)
   gtk_widget_show (toolsDefaultHighlighter);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsDefaultHighlighter);
 
-  toolsDefaultText = gtk_menu_item_new_with_mnemonic ("Default Text");
+  toolsDefaultText = gtk_menu_item_new_with_mnemonic ("Default Te_xt");
   gtk_widget_show (toolsDefaultText);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsDefaultText);
 
-  toolsSetAsDefault = gtk_menu_item_new_with_mnemonic ("Set As Default");
+  toolsSetAsDefault = gtk_menu_item_new_with_mnemonic ("_Set As Default");
   gtk_widget_show (toolsSetAsDefault);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsSetAsDefault);
 
@@ -1086,9 +1159,12 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuTools_menu), separator15);
   gtk_widget_set_sensitive (separator15, FALSE);
 
-  toolsRuler = gtk_check_menu_item_new_with_mnemonic ("Ruler");
+  toolsRuler = gtk_check_menu_item_new_with_mnemonic ("Ru_ler");
   gtk_widget_show (toolsRuler);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsRuler);
+  gtk_widget_add_accelerator (toolsRuler, "activate", accel_group,
+                              GDK_L, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
 
   menuOptions = gtk_menu_item_new_with_mnemonic ("_Options");
   gtk_widget_show (menuOptions);
@@ -1097,68 +1173,68 @@ create_winMain (void)
   menuOptions_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuOptions), menuOptions_menu);
 
-  optionsUseXInput = gtk_check_menu_item_new_with_mnemonic ("Use XInput");
+  optionsUseXInput = gtk_check_menu_item_new_with_mnemonic ("Use _XInput");
   gtk_widget_show (optionsUseXInput);
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), optionsUseXInput);
 
-  optionsDiscardCoreEvents = gtk_check_menu_item_new_with_mnemonic ("Discard Core Events");
+  optionsDiscardCoreEvents = gtk_check_menu_item_new_with_mnemonic ("Discard _Core Events");
   gtk_widget_show (optionsDiscardCoreEvents);
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), optionsDiscardCoreEvents);
 
-  optionsButtonMappings = gtk_check_menu_item_new_with_mnemonic ("Eraser Tip");
+  optionsButtonMappings = gtk_check_menu_item_new_with_mnemonic ("_Eraser Tip");
   gtk_widget_show (optionsButtonMappings);
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), optionsButtonMappings);
 
-  button2_mapping = gtk_menu_item_new_with_mnemonic ("Button 2 Mapping");
+  button2_mapping = gtk_menu_item_new_with_mnemonic ("Button _2 Mapping");
   gtk_widget_show (button2_mapping);
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), button2_mapping);
 
   button2_mapping_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (button2_mapping), button2_mapping_menu);
 
-  button2Pen = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Pen");
+  button2Pen = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "_Pen");
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2Pen));
   gtk_widget_show (button2Pen);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2Pen);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2Pen), TRUE);
 
-  button2Eraser = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Eraser");
+  button2Eraser = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "_Eraser");
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2Eraser));
   gtk_widget_show (button2Eraser);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2Eraser);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2Eraser), TRUE);
 
-  button2Highlighter = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Highlighter");
+  button2Highlighter = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "_Highlighter");
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2Highlighter));
   gtk_widget_show (button2Highlighter);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2Highlighter);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2Highlighter), TRUE);
 
-  button2Text = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Text");
+  button2Text = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "_Text");
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2Text));
   gtk_widget_show (button2Text);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2Text);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2Text), TRUE);
 
-  button2SelectRegion = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Select Region");
+  button2SelectRegion = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Select Re_gion");
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2SelectRegion));
   gtk_widget_show (button2SelectRegion);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2SelectRegion);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2SelectRegion), TRUE);
 
-  button2SelectRectangle = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Select Rectangle");
+  button2SelectRectangle = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Select _Rectangle");
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2SelectRectangle));
   gtk_widget_show (button2SelectRectangle);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2SelectRectangle);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2SelectRectangle), TRUE);
 
-  button2VerticalSpace = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Vertical Space");
+  button2VerticalSpace = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "_Vertical Space");
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2VerticalSpace));
   gtk_widget_show (button2VerticalSpace);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2VerticalSpace);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2VerticalSpace), TRUE);
 
-  button2Hand = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "Hand Tool");
+  button2Hand = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, "H_and Tool");
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2Hand));
   gtk_widget_show (button2Hand);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2Hand);
@@ -1168,13 +1244,13 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), separator24);
   gtk_widget_set_sensitive (separator24, FALSE);
 
-  button2LinkBrush = gtk_radio_menu_item_new_with_mnemonic (button2LinkBrush_group, "Link to Primary Brush");
+  button2LinkBrush = gtk_radio_menu_item_new_with_mnemonic (button2LinkBrush_group, "_Link to Primary Brush");
   button2LinkBrush_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2LinkBrush));
   gtk_widget_show (button2LinkBrush);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2LinkBrush);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2LinkBrush), TRUE);
 
-  button2CopyBrush = gtk_radio_menu_item_new_with_mnemonic (button2LinkBrush_group, "Copy of Current Brush");
+  button2CopyBrush = gtk_radio_menu_item_new_with_mnemonic (button2LinkBrush_group, "_Copy of Current Brush");
   button2LinkBrush_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2CopyBrush));
   gtk_widget_show (button2CopyBrush);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2CopyBrush);
@@ -1185,56 +1261,56 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2NABrush);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2NABrush), TRUE);
 
-  button3_mapping = gtk_menu_item_new_with_mnemonic ("Button 3 Mapping");
+  button3_mapping = gtk_menu_item_new_with_mnemonic ("Button _3 Mapping");
   gtk_widget_show (button3_mapping);
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), button3_mapping);
 
   button3_mapping_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (button3_mapping), button3_mapping_menu);
 
-  button3Pen = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Pen");
+  button3Pen = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "_Pen");
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3Pen));
   gtk_widget_show (button3Pen);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3Pen);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3Pen), TRUE);
 
-  button3Eraser = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Eraser");
+  button3Eraser = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "_Eraser");
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3Eraser));
   gtk_widget_show (button3Eraser);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3Eraser);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3Eraser), TRUE);
 
-  button3Highlighter = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Highlighter");
+  button3Highlighter = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "_Highlighter");
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3Highlighter));
   gtk_widget_show (button3Highlighter);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3Highlighter);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3Highlighter), TRUE);
 
-  button3Text = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Text");
+  button3Text = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "_Text");
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3Text));
   gtk_widget_show (button3Text);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3Text);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3Text), TRUE);
 
-  button3SelectRegion = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Select Region");
+  button3SelectRegion = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Select Re_gion");
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3SelectRegion));
   gtk_widget_show (button3SelectRegion);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3SelectRegion);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3SelectRegion), TRUE);
 
-  button3SelectRectangle = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Select Rectangle");
+  button3SelectRectangle = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Select _Rectangle");
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3SelectRectangle));
   gtk_widget_show (button3SelectRectangle);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3SelectRectangle);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3SelectRectangle), TRUE);
 
-  button3VerticalSpace = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Vertical Space");
+  button3VerticalSpace = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "_Vertical Space");
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3VerticalSpace));
   gtk_widget_show (button3VerticalSpace);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3VerticalSpace);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3VerticalSpace), TRUE);
 
-  button3Hand = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "Hand Tool");
+  button3Hand = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, "H_and Tool");
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3Hand));
   gtk_widget_show (button3Hand);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3Hand);
@@ -1244,13 +1320,13 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), separator25);
   gtk_widget_set_sensitive (separator25, FALSE);
 
-  button3LinkBrush = gtk_radio_menu_item_new_with_mnemonic (button3LinkBrush_group, "Link to Primary Brush");
+  button3LinkBrush = gtk_radio_menu_item_new_with_mnemonic (button3LinkBrush_group, "_Link to Primary Brush");
   button3LinkBrush_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3LinkBrush));
   gtk_widget_show (button3LinkBrush);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3LinkBrush);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3LinkBrush), TRUE);
 
-  button3CopyBrush = gtk_radio_menu_item_new_with_mnemonic (button3LinkBrush_group, "Copy of Current Brush");
+  button3CopyBrush = gtk_radio_menu_item_new_with_mnemonic (button3LinkBrush_group, "_Copy of Current Brush");
   button3LinkBrush_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3CopyBrush));
   gtk_widget_show (button3CopyBrush);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3CopyBrush);
@@ -1266,15 +1342,15 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), separator18);
   gtk_widget_set_sensitive (separator18, FALSE);
 
-  optionsAntialiasBG = gtk_check_menu_item_new_with_mnemonic ("Antialiased Bitmaps");
+  optionsAntialiasBG = gtk_check_menu_item_new_with_mnemonic ("_Antialiased Bitmaps");
   gtk_widget_show (optionsAntialiasBG);
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), optionsAntialiasBG);
 
-  optionsProgressiveBG = gtk_check_menu_item_new_with_mnemonic ("Progressive Backgrounds");
+  optionsProgressiveBG = gtk_check_menu_item_new_with_mnemonic ("_Progressive Backgrounds");
   gtk_widget_show (optionsProgressiveBG);
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), optionsProgressiveBG);
 
-  optionsPrintRuling = gtk_check_menu_item_new_with_mnemonic ("Print Paper Ruling");
+  optionsPrintRuling = gtk_check_menu_item_new_with_mnemonic ("Print Paper _Ruling");
   gtk_widget_show (optionsPrintRuling);
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), optionsPrintRuling);
 
@@ -1283,7 +1359,7 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), separator21);
   gtk_widget_set_sensitive (separator21, FALSE);
 
-  optionsSavePreferences = gtk_menu_item_new_with_mnemonic ("Save Preferences");
+  optionsSavePreferences = gtk_menu_item_new_with_mnemonic ("_Save Preferences");
   gtk_widget_show (optionsSavePreferences);
   gtk_container_add (GTK_CONTAINER (menuOptions_menu), optionsSavePreferences);
 
@@ -1767,6 +1843,24 @@ create_winMain (void)
   gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonColorOther), buttonBlack_group);
   buttonBlack_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (buttonColorOther));
 
+  toolitem21 = (GtkWidget*) gtk_tool_item_new ();
+  gtk_widget_show (toolitem21);
+  gtk_container_add (GTK_CONTAINER (toolbarPen), toolitem21);
+
+  vseparator10 = gtk_vseparator_new ();
+  gtk_widget_show (vseparator10);
+  gtk_container_add (GTK_CONTAINER (toolitem21), vseparator10);
+
+  toolitem20 = (GtkWidget*) gtk_tool_item_new ();
+  gtk_widget_show (toolitem20);
+  gtk_container_add (GTK_CONTAINER (toolbarPen), toolitem20);
+
+  fontButton = gtk_font_button_new ();
+  gtk_widget_show (fontButton);
+  gtk_container_add (GTK_CONTAINER (toolitem20), fontButton);
+  gtk_font_button_set_use_font (GTK_FONT_BUTTON (fontButton), TRUE);
+  gtk_button_set_focus_on_click (GTK_BUTTON (fontButton), FALSE);
+
   scrolledwindowMain = gtk_scrolled_window_new (NULL, NULL);
   gtk_widget_show (scrolledwindowMain);
   gtk_box_pack_start (GTK_BOX (vboxMain), scrolledwindowMain, TRUE, TRUE, 0);
@@ -2333,6 +2427,9 @@ create_winMain (void)
   g_signal_connect ((gpointer) buttonWhite, "toggled",
                     G_CALLBACK (on_colorWhite_activate),
                     NULL);
+  g_signal_connect ((gpointer) fontButton, "font_set",
+                    G_CALLBACK (on_fontButton_font_set),
+                    NULL);
   g_signal_connect ((gpointer) spinPageNo, "value_changed",
                     G_CALLBACK (on_spinPageNo_value_changed),
                     NULL);
@@ -2611,6 +2708,10 @@ create_winMain (void)
   GLADE_HOOKUP_OBJECT (winMain, buttonYellow, "buttonYellow");
   GLADE_HOOKUP_OBJECT (winMain, buttonWhite, "buttonWhite");
   GLADE_HOOKUP_OBJECT (winMain, buttonColorOther, "buttonColorOther");
+  GLADE_HOOKUP_OBJECT (winMain, toolitem21, "toolitem21");
+  GLADE_HOOKUP_OBJECT (winMain, vseparator10, "vseparator10");
+  GLADE_HOOKUP_OBJECT (winMain, toolitem20, "toolitem20");
+  GLADE_HOOKUP_OBJECT (winMain, fontButton, "fontButton");
   GLADE_HOOKUP_OBJECT (winMain, scrolledwindowMain, "scrolledwindowMain");
   GLADE_HOOKUP_OBJECT (winMain, hbox1, "hbox1");
   GLADE_HOOKUP_OBJECT (winMain, labelPage, "labelPage");
@@ -2627,84 +2728,6 @@ create_winMain (void)
   return winMain;
 }
 
-GtkWidget*
-create_fontDialog (void)
-{
-  GtkWidget *fontDialog;
-  GtkWidget *ok_button1;
-  GtkWidget *cancel_button1;
-  GtkWidget *apply_button1;
-  GtkWidget *font_selection1;
-
-  fontDialog = gtk_font_selection_dialog_new ("Select Font");
-  gtk_container_set_border_width (GTK_CONTAINER (fontDialog), 4);
-  gtk_window_set_type_hint (GTK_WINDOW (fontDialog), GDK_WINDOW_TYPE_HINT_DIALOG);
-
-  ok_button1 = GTK_FONT_SELECTION_DIALOG (fontDialog)->ok_button;
-  gtk_widget_show (ok_button1);
-  GTK_WIDGET_SET_FLAGS (ok_button1, GTK_CAN_DEFAULT);
-
-  cancel_button1 = GTK_FONT_SELECTION_DIALOG (fontDialog)->cancel_button;
-  gtk_widget_show (cancel_button1);
-  GTK_WIDGET_SET_FLAGS (cancel_button1, GTK_CAN_DEFAULT);
-
-  apply_button1 = GTK_FONT_SELECTION_DIALOG (fontDialog)->apply_button;
-  gtk_widget_show (apply_button1);
-  GTK_WIDGET_SET_FLAGS (apply_button1, GTK_CAN_DEFAULT);
-
-  font_selection1 = GTK_FONT_SELECTION_DIALOG (fontDialog)->fontsel;
-  gtk_widget_show (font_selection1);
-  gtk_container_set_border_width (GTK_CONTAINER (font_selection1), 4);
-
-  /* Store pointers to all widgets, for use by lookup_widget(). */
-  GLADE_HOOKUP_OBJECT_NO_REF (fontDialog, fontDialog, "fontDialog");
-  GLADE_HOOKUP_OBJECT_NO_REF (fontDialog, ok_button1, "ok_button1");
-  GLADE_HOOKUP_OBJECT_NO_REF (fontDialog, cancel_button1, "cancel_button1");
-  GLADE_HOOKUP_OBJECT_NO_REF (fontDialog, apply_button1, "apply_button1");
-  GLADE_HOOKUP_OBJECT_NO_REF (fontDialog, font_selection1, "font_selection1");
-
-  return fontDialog;
-}
-
-GtkWidget*
-create_colorChooserDialog (void)
-{
-  GtkWidget *colorChooserDialog;
-  GtkWidget *ok_button2;
-  GtkWidget *cancel_button2;
-  GtkWidget *help_button1;
-  GtkWidget *color_selection1;
-
-  colorChooserDialog = gtk_color_selection_dialog_new ("Select Color");
-  gtk_window_set_resizable (GTK_WINDOW (colorChooserDialog), FALSE);
-  gtk_window_set_type_hint (GTK_WINDOW (colorChooserDialog), GDK_WINDOW_TYPE_HINT_DIALOG);
-
-  ok_button2 = GTK_COLOR_SELECTION_DIALOG (colorChooserDialog)->ok_button;
-  gtk_widget_show (ok_button2);
-  GTK_WIDGET_SET_FLAGS (ok_button2, GTK_CAN_DEFAULT);
-
-  cancel_button2 = GTK_COLOR_SELECTION_DIALOG (colorChooserDialog)->cancel_button;
-  gtk_widget_show (cancel_button2);
-  GTK_WIDGET_SET_FLAGS (cancel_button2, GTK_CAN_DEFAULT);
-
-  help_button1 = GTK_COLOR_SELECTION_DIALOG (colorChooserDialog)->help_button;
-  gtk_widget_show (help_button1);
-  GTK_WIDGET_SET_FLAGS (help_button1, GTK_CAN_DEFAULT);
-
-  color_selection1 = GTK_COLOR_SELECTION_DIALOG (colorChooserDialog)->colorsel;
-  gtk_widget_show (color_selection1);
-  gtk_color_selection_set_has_opacity_control (GTK_COLOR_SELECTION (color_selection1), FALSE);
-
-  /* Store pointers to all widgets, for use by lookup_widget(). */
-  GLADE_HOOKUP_OBJECT_NO_REF (colorChooserDialog, colorChooserDialog, "colorChooserDialog");
-  GLADE_HOOKUP_OBJECT_NO_REF (colorChooserDialog, ok_button2, "ok_button2");
-  GLADE_HOOKUP_OBJECT_NO_REF (colorChooserDialog, cancel_button2, "cancel_button2");
-  GLADE_HOOKUP_OBJECT_NO_REF (colorChooserDialog, help_button1, "help_button1");
-  GLADE_HOOKUP_OBJECT_NO_REF (colorChooserDialog, color_selection1, "color_selection1");
-
-  return colorChooserDialog;
-}
-
 GtkWidget*
 create_papersizeDialog (void)
 {
index 08921ca7a427d9bd6b93b115261e2b5c04e2878a..1e8679206b28f272839179303832ee679060c7e2 100644 (file)
@@ -3,8 +3,6 @@
  */
 
 GtkWidget* create_winMain (void);
-GtkWidget* create_fontDialog (void);
-GtkWidget* create_colorChooserDialog (void);
 GtkWidget* create_papersizeDialog (void);
 GtkWidget* create_aboutDialog (void);
 GtkWidget* create_zoomDialog (void);
index 7cfe98410d068ef218476d7fb5eec14090afae5d..619ab17ca1eac3811b11a6f378b88986c89e6552 100644 (file)
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <gtk/gtk.h>
 #include <libgnomecanvas/libgnomecanvas.h>
+#include <gdk/gdkkeysyms.h>
 
 #include "xournal.h"
 #include "xo-interface.h"
@@ -126,6 +127,11 @@ void clear_redo_stack(void)
       g_free(redo->item);
       /* the strokes are unmapped, so there are no associated canvas items */
     }
+    else if (redo->type == ITEM_TEXT) {
+      g_free(redo->item->text);
+      g_free(redo->item->font_name);
+      g_free(redo->item);
+    }
     else if (redo->type == ITEM_ERASURE) {
       for (list = redo->erasurelist; list!=NULL; list=list->next) {
         erasure = (struct UndoErasureData *)list->data;
@@ -165,6 +171,10 @@ void clear_redo_stack(void)
     else if (redo->type == ITEM_NEW_LAYER) {
       g_free(redo->layer);
     }
+    else if (redo->type == ITEM_TEXT_EDIT || redo->type == ITEM_TEXT_ATTRIB) {
+      g_free(redo->str);
+      if (redo->type == ITEM_TEXT_ATTRIB) g_free(redo->brush);
+    }
 
     u = redo;
     redo = redo->next;
@@ -185,7 +195,10 @@ void clear_undo_stack(void)
     if (undo->type == ITEM_ERASURE) {
       for (list = undo->erasurelist; list!=NULL; list=list->next) {
         erasure = (struct UndoErasureData *)list->data;
-        gnome_canvas_points_free(erasure->item->path);
+        if (erasure->item->type == ITEM_STROKE)
+          gnome_canvas_points_free(erasure->item->path);
+        if (erasure->item->type == ITEM_TEXT)
+          { g_free(erasure->item->text); g_free(erasure->item->font_name); }
         g_free(erasure->item);
         g_list_free(erasure->replacement_items);
         g_free(erasure);
@@ -214,6 +227,10 @@ void clear_undo_stack(void)
       undo->page->group = NULL;
       delete_page(undo->page);
     }
+    else if (undo->type == ITEM_TEXT_EDIT || undo->type == ITEM_TEXT_ATTRIB) {
+      g_free(undo->str);
+      if (undo->type == ITEM_TEXT_ATTRIB) g_free(undo->brush);
+    }
 
     u = undo;
     undo = undo->next;
@@ -260,6 +277,9 @@ void delete_layer(struct Layer *l)
     item = (struct Item *)l->items->data;
     if (item->type == ITEM_STROKE && item->path != NULL) 
       gnome_canvas_points_free(item->path);
+    if (item->type == ITEM_TEXT) {
+      g_free(item->font_name); g_free(item->text);
+    }
     // don't need to delete the canvas_item, as it's part of the group destroyed below
     g_free(item);
     l->items = g_list_delete_link(l->items, l->items);
@@ -310,10 +330,11 @@ void get_pointer_coords(GdkEvent *event, gdouble *ret)
 
 void fix_xinput_coords(GdkEvent *event)
 {
+#ifdef ENABLE_XINPUT_BUGFIX
   double *axes, *px, *py, axis_width;
   GdkDevice *device;
   int wx, wy, sx, sy;
-  
+
   if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) {
     axes = event->button.axes;
     px = &(event->button.x);
@@ -329,7 +350,9 @@ void fix_xinput_coords(GdkEvent *event)
   else return; // nothing we know how to do
   
   gdk_window_get_origin(event->any.window, &wx, &wy);
-  gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
+  // somehow, behavior changed starting with GTK+ 2.11.0
+  if (!gtk_check_version(2, 11, 0)) sx = sy = 0;
+  else gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
   
   axis_width = device->axes[0].max - device->axes[0].min;
   if (axis_width>EPSILON)
@@ -338,12 +361,13 @@ void fix_xinput_coords(GdkEvent *event)
   axis_width = device->axes[1].max - device->axes[1].min;
   if (axis_width>EPSILON)
     *py = (axes[1]/axis_width)*ui.screen_height + sy - wy;
+#endif
 }
 
 void update_item_bbox(struct Item *item)
 {
   int i;
-  double *p;
+  gdouble *p, h, w;
   
   if (item->type == ITEM_STROKE) {
     item->bbox.left = item->bbox.right = item->path->coords[0];
@@ -356,6 +380,12 @@ void update_item_bbox(struct Item *item)
       if (p[1] > item->bbox.bottom) item->bbox.bottom = p[1];
     }
   }
+  if (item->type == ITEM_TEXT && item->canvas_item!=NULL) {
+    h=0.; w=0.;
+    g_object_get(item->canvas_item, "text_width", &w, "text_height", &h, NULL);
+    item->bbox.right = item->bbox.left + w;
+    item->bbox.bottom = item->bbox.top + h;
+  }
 }
 
 void make_page_clipbox(struct Page *pg)
@@ -372,6 +402,30 @@ void make_page_clipbox(struct Page *pg)
   gnome_canvas_path_def_unref(pg_clip);
 }
 
+void make_canvas_item_one(GnomeCanvasGroup *group, struct Item *item)
+{
+  GnomeCanvasItem *i;
+  PangoFontDescription *font_desc;
+
+  if (item->type == ITEM_STROKE)
+    item->canvas_item = gnome_canvas_item_new(group,
+          gnome_canvas_line_get_type(), "points", item->path,   
+          "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
+          "fill-color-rgba", item->brush.color_rgba,  
+          "width-units", item->brush.thickness, NULL);
+  if (item->type == ITEM_TEXT) {
+    font_desc = pango_font_description_from_string(item->font_name);
+    pango_font_description_set_absolute_size(font_desc, 
+            item->font_size*ui.zoom*PANGO_SCALE);
+    item->canvas_item = gnome_canvas_item_new(group,
+          gnome_canvas_text_get_type(),
+          "x", item->bbox.left, "y", item->bbox.top, "anchor", GTK_ANCHOR_NW,
+          "font-desc", font_desc, "fill-color-rgba", item->brush.color_rgba,
+          "text", item->text, NULL);
+    update_item_bbox(item);
+  }
+}
+
 void make_canvas_items(void)
 {
   struct Page *pg;
@@ -394,13 +448,8 @@ void make_canvas_items(void)
            pg->group, gnome_canvas_group_get_type(), NULL);
       for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next) {
         item = (struct Item *)itemlist->data;
-        if (item->type == ITEM_STROKE && item->canvas_item == NULL) {
-          item->canvas_item = gnome_canvas_item_new(l->group,
-              gnome_canvas_line_get_type(), "points", item->path,
-              "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-              "fill-color-rgba", item->brush.color_rgba,
-              "width-units", item->brush.thickness, NULL);
-        }
+        if (item->canvas_item == NULL)
+          make_canvas_item_one(l->group, item);
       }
     }
   }
@@ -586,6 +635,14 @@ void lower_canvas_item_to(GnomeCanvasGroup *g, GnomeCanvasItem *item, GnomeCanva
   g->item_list_end = g_list_last(g->item_list);
 }
 
+void rgb_to_gdkcolor(guint rgba, GdkColor *color)
+{
+  color->pixel = 0;
+  color->red = ((rgba>>24)&0xff)*0x101;
+  color->green = ((rgba>>16)&0xff)*0x101;
+  color->blue = ((rgba>>8)&0xff)*0x101;
+}
+
 // some interface functions
 
 void update_thickness_buttons(void)
@@ -616,7 +673,7 @@ void update_thickness_buttons(void)
 void update_color_buttons(void)
 {
   if (ui.selection!=NULL || (ui.toolno[ui.cur_mapping] != TOOL_PEN 
-                          && ui.toolno[ui.cur_mapping] != TOOL_HIGHLIGHTER)) {
+      && ui.toolno[ui.cur_mapping] != TOOL_HIGHLIGHTER && ui.toolno[ui.cur_mapping] != TOOL_TEXT)) {
     gtk_toggle_tool_button_set_active(
       GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonColorOther")), TRUE);
   } else
@@ -766,7 +823,7 @@ void update_ruler_indicator(void)
 void update_color_menu(void)
 {
   if (ui.selection!=NULL || (ui.toolno[ui.cur_mapping] != TOOL_PEN 
-                          && ui.toolno[ui.cur_mapping] != TOOL_HIGHLIGHTER)) {
+    && ui.toolno[ui.cur_mapping] != TOOL_HIGHLIGHTER && ui.toolno[ui.cur_mapping] != TOOL_TEXT)) {
     gtk_check_menu_item_set_active(
       GTK_CHECK_MENU_ITEM(GET_COMPONENT("colorNA")), TRUE);
   } else
@@ -928,7 +985,8 @@ void update_mappings_menu_linkings(void)
 void update_mappings_menu(void)
 {
   gtk_widget_set_sensitive(GET_COMPONENT("optionsButtonMappings"), ui.use_xinput);
-  gtk_widget_set_sensitive(GET_COMPONENT("optionsDiscardCoreEvents"), ui.use_xinput);
+  gtk_widget_set_sensitive(GET_COMPONENT("optionsDiscardCoreEvents"), 
+    ui.use_xinput && (gtk_check_version(2, 11, 0)!=NULL));
   gtk_check_menu_item_set_active(
     GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsButtonMappings")), ui.use_erasertip);
   gtk_check_menu_item_set_active(
@@ -999,7 +1057,7 @@ void update_mappings_menu(void)
 
 void do_switch_page(int pg, gboolean rescroll, gboolean refresh_all)
 {
-  int i;
+  int i, cx, cy;
   struct Layer *layer;
   GList *list;
   
@@ -1020,8 +1078,13 @@ void do_switch_page(int pg, gboolean rescroll, gboolean refresh_all)
   if (ui.progressive_bg) rescale_bg_pixmaps();
  
   if (rescroll) { // scroll and force a refresh
+/* -- this seems to cause some display bugs ??
     gtk_adjustment_set_value(gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)),
-      ui.cur_page->voffset*ui.zoom);
+      ui.cur_page->voffset*ui.zoom);  */
+    gnome_canvas_get_scroll_offsets(canvas, &cx, &cy);
+    cy = ui.cur_page->voffset*ui.zoom;
+    gnome_canvas_scroll_to(canvas, cx, cy);
+    
     if (refresh_all) 
       gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
     else if (!ui.view_continuous)
@@ -1232,9 +1295,11 @@ void update_copy_paste_enabled(void)
 {
   gtk_widget_set_sensitive(GET_COMPONENT("editCut"), ui.selection!=NULL);
   gtk_widget_set_sensitive(GET_COMPONENT("editCopy"), ui.selection!=NULL);
+  gtk_widget_set_sensitive(GET_COMPONENT("editPaste"), ui.cur_item_type!=ITEM_TEXT);
   gtk_widget_set_sensitive(GET_COMPONENT("editDelete"), ui.selection!=NULL);
   gtk_widget_set_sensitive(GET_COMPONENT("buttonCut"), ui.selection!=NULL);
   gtk_widget_set_sensitive(GET_COMPONENT("buttonCopy"), ui.selection!=NULL);
+  gtk_widget_set_sensitive(GET_COMPONENT("buttonPaste"), ui.cur_item_type!=ITEM_TEXT);
 }
 
 void update_mapping_linkings(int toolno)
@@ -1260,12 +1325,32 @@ void set_cur_color(int color)
 {
   ui.cur_brush->color_no = color;
   if (ui.toolno[0] == TOOL_HIGHLIGHTER)
-    ui.cur_brush->color_rgba = predef_colors_rgba[color] & HILITER_ALPHA_MASK;
+    ui.cur_brush->color_rgba = predef_colors_rgba[color] & ui.hiliter_alpha_mask;
   else
     ui.cur_brush->color_rgba = predef_colors_rgba[color];
   update_mapping_linkings(ui.toolno[0]);
 }
 
+void recolor_temp_text(int color_no, guint color_rgba)
+{
+  GdkColor gdkcolor;
+  
+  if (ui.cur_item_type!=ITEM_TEXT) return;
+  if (ui.cur_item->text!=NULL && ui.cur_item->brush.color_rgba != color_rgba) {
+    prepare_new_undo();
+    undo->type = ITEM_TEXT_ATTRIB;
+    undo->item = ui.cur_item;
+    undo->str = g_strdup(ui.cur_item->font_name);
+    undo->val_x = ui.cur_item->font_size;
+    undo->brush = (struct Brush *)g_memdup(&(ui.cur_item->brush), sizeof(struct Brush));
+  }
+  ui.cur_item->brush.color_no = color_no;
+  ui.cur_item->brush.color_rgba = color_rgba;
+  rgb_to_gdkcolor(color_rgba, &gdkcolor);
+  gtk_widget_modify_text(ui.cur_item->widget, GTK_STATE_NORMAL, &gdkcolor);
+  gtk_widget_grab_focus(ui.cur_item->widget);
+}
+
 void process_color_activate(GtkMenuItem *menuitem, int color)
 {
   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
@@ -1277,6 +1362,10 @@ void process_color_activate(GtkMenuItem *menuitem, int color)
   }
 
   if (ui.cur_mapping != 0) return; // not user-generated
+  reset_focus();
+
+  if (ui.cur_item_type == ITEM_TEXT)
+    recolor_temp_text(color, predef_colors_rgba[color]);
 
   if (ui.selection != NULL) {
     recolor_selection(color);
@@ -1284,8 +1373,10 @@ void process_color_activate(GtkMenuItem *menuitem, int color)
     update_color_menu();
   }
   
-  if (ui.toolno[0] != TOOL_PEN && ui.toolno[0] != TOOL_HIGHLIGHTER) {
+  if (ui.toolno[0] != TOOL_PEN && ui.toolno[0] != TOOL_HIGHLIGHTER
+      && ui.toolno[0] != TOOL_TEXT) {
     if (ui.selection != NULL) return;
+    end_text();
     ui.toolno[0] = TOOL_PEN;
     ui.cur_brush = &(ui.brushes[0][TOOL_PEN]);
     update_tool_buttons();
@@ -1311,6 +1402,7 @@ void process_thickness_activate(GtkMenuItem *menuitem, int tool, int val)
   if (ui.cur_mapping != 0) return; // not user-generated
 
   if (ui.selection != NULL && GTK_OBJECT_TYPE(menuitem) != GTK_TYPE_RADIO_MENU_ITEM) {
+    reset_focus();
     rethicken_selection(val);
     update_thickness_buttons();
   }
@@ -1320,6 +1412,9 @@ void process_thickness_activate(GtkMenuItem *menuitem, int tool, int val)
     return;
   }
 
+  if (ui.brushes[0][tool].thickness_no == val) return;
+  reset_focus();
+  end_text();
   ui.brushes[0][tool].thickness_no = val;
   ui.brushes[0][tool].thickness = predef_thickness[tool][val];
   update_mapping_linkings(tool);
@@ -1440,6 +1535,15 @@ gboolean page_ops_forbidden(void)
   return (bgpdf.status != STATUS_NOT_INIT && bgpdf.create_pages);
 }
 
+// send the focus back to the appropriate widget
+void reset_focus(void)
+{
+  if (ui.cur_item_type == ITEM_TEXT)
+    gtk_widget_grab_focus(ui.cur_item->widget);
+  else
+    gtk_widget_grab_focus(GTK_WIDGET(canvas));
+}
+
 // selection / clipboard stuff
 
 void reset_selection(void)
@@ -1454,6 +1558,7 @@ void reset_selection(void)
   update_color_menu();
   update_thickness_buttons();
   update_color_buttons();
+  update_font_button();
 }
 
 void move_journal_items_by(GList *itemlist, double dx, double dy,
@@ -1467,9 +1572,10 @@ void move_journal_items_by(GList *itemlist, double dx, double dy,
   
   while (itemlist!=NULL) {
     item = (struct Item *)itemlist->data;
-    if (item->type == ITEM_STROKE) {
+    if (item->type == ITEM_STROKE)
       for (pt=item->path->coords, i=0; i<item->path->num_points; i++, pt+=2)
         { pt[0] += dx; pt[1] += dy; }
+    if (item->type == ITEM_STROKE || item->type == ITEM_TEXT || item->type == ITEM_TEMP_TEXT) {
       item->bbox.left += dx;
       item->bbox.right += dx;
       item->bbox.top += dy;
@@ -1515,6 +1621,8 @@ void switch_mapping(int m)
   ui.cur_mapping = m;
   if (ui.toolno[m] < NUM_STROKE_TOOLS) 
     ui.cur_brush = &(ui.brushes[m][ui.toolno[m]]);
+  if (ui.toolno[m] == TOOL_TEXT)
+    ui.cur_brush = &(ui.brushes[m][TOOL_PEN]);
   update_tool_buttons();
   update_color_menu();
   update_cursor();
@@ -1525,6 +1633,9 @@ void process_mapping_activate(GtkMenuItem *menuitem, int m, int tool)
   if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
   if (ui.cur_mapping!=0) return;
   if (ui.toolno[m] == tool) return;
+  end_text();
+  reset_focus();
+    
   ui.toolno[m] = tool;
   ui.ruler[m] = FALSE;
   if (ui.linked_brush[m] == BRUSH_LINKED 
@@ -1561,3 +1672,141 @@ void update_vbox_order(int *order)
     if (!present[i]) gtk_widget_hide(GET_COMPONENT(vbox_component_names[i]));
 }
 
+gchar *make_cur_font_name(void)
+{
+  gchar *str;
+  struct Item *it;
+
+  if (ui.cur_item_type == ITEM_TEXT)
+    str = g_strdup_printf("%s %.1f", ui.cur_item->font_name, ui.cur_item->font_size);
+  else if (ui.selection!=NULL && ui.selection->items!=NULL &&
+           ui.selection->items->next==NULL &&
+           (it=(struct Item*)ui.selection->items->data)->type == ITEM_TEXT)
+    str = g_strdup_printf("%s %.1f", it->font_name, it->font_size);
+  else
+    str = g_strdup_printf("%s %.1f", ui.font_name, ui.font_size);
+  return str;
+}
+
+void update_font_button(void)
+{
+  gchar *str;
+
+  str = make_cur_font_name();
+  gtk_font_button_set_font_name(GTK_FONT_BUTTON(GET_COMPONENT("fontButton")), str);
+  g_free(str);
+}
+
+gboolean can_accel(GtkWidget *widget, guint id, gpointer data)
+{
+  return GTK_WIDGET_SENSITIVE(widget);
+}
+
+void allow_all_accels(void)
+{
+  g_signal_connect((gpointer) GET_COMPONENT("fileNew"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("fileOpen"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("fileSave"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("filePrint"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("filePrintPDF"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("fileQuit"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("editUndo"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("editRedo"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("editCut"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("editCopy"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("editPaste"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("editDelete"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("viewFullscreen"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("viewZoomIn"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("viewZoomOut"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("viewNormalSize"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("viewPageWidth"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("viewFirstPage"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("viewPreviousPage"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("viewNextPage"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("viewLastPage"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("toolsPen"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("toolsEraser"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("toolsHighlighter"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("toolsText"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+/*  g_signal_connect((gpointer) GET_COMPONENT("toolsSelectRegion"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);  */
+  g_signal_connect((gpointer) GET_COMPONENT("toolsSelectRectangle"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("toolsVerticalSpace"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("toolsHand"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("toolsTextFont"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+  g_signal_connect((gpointer) GET_COMPONENT("toolsRuler"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
+}
+
+void add_scroll_bindings(void)
+{
+  GtkBindingSet *binding_set;
+  
+  binding_set = gtk_binding_set_by_class(
+     G_OBJECT_GET_CLASS(GET_COMPONENT("scrolledwindowMain")));
+  gtk_binding_entry_add_signal(binding_set, GDK_Up, 0,
+    "scroll_child", 2, GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_BACKWARD, 
+    G_TYPE_BOOLEAN, FALSE);  
+  gtk_binding_entry_add_signal(binding_set, GDK_KP_Up, 0,
+    "scroll_child", 2, GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_BACKWARD, 
+    G_TYPE_BOOLEAN, FALSE);  
+  gtk_binding_entry_add_signal(binding_set, GDK_Down, 0,
+    "scroll_child", 2, GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_FORWARD, 
+    G_TYPE_BOOLEAN, FALSE);  
+  gtk_binding_entry_add_signal(binding_set, GDK_KP_Down, 0,
+    "scroll_child", 2, GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_FORWARD, 
+    G_TYPE_BOOLEAN, FALSE);  
+  gtk_binding_entry_add_signal(binding_set, GDK_Left, 0,
+    "scroll_child", 2, GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_BACKWARD, 
+    G_TYPE_BOOLEAN, TRUE);  
+  gtk_binding_entry_add_signal(binding_set, GDK_KP_Left, 0,
+    "scroll_child", 2, GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_BACKWARD, 
+    G_TYPE_BOOLEAN, TRUE);  
+  gtk_binding_entry_add_signal(binding_set, GDK_Right, 0,
+    "scroll_child", 2, GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_FORWARD, 
+    G_TYPE_BOOLEAN, TRUE);  
+  gtk_binding_entry_add_signal(binding_set, GDK_KP_Right, 0,
+    "scroll_child", 2, GTK_TYPE_SCROLL_TYPE, GTK_SCROLL_STEP_FORWARD, 
+    G_TYPE_BOOLEAN, TRUE);  
+}
+
+gboolean is_event_within_textview(GdkEventButton *event)
+{
+  double pt[2];
+  
+  if (ui.cur_item_type!=ITEM_TEXT) return FALSE;
+  get_pointer_coords((GdkEvent *)event, pt);
+  if (pt[0]<ui.cur_item->bbox.left || pt[0]>ui.cur_item->bbox.right) return FALSE;
+  if (pt[1]<ui.cur_item->bbox.top || pt[1]>ui.cur_item->bbox.bottom) return FALSE;
+  return TRUE;
+}
index a82d3716dbeabdd86bac0b03e3c89ad0a53ec0cf..e8f1d118f417cd6413ec4b5b705e74d1911cfc61 100644 (file)
@@ -23,6 +23,7 @@ void fix_xinput_coords(GdkEvent *event);
 void update_item_bbox(struct Item *item);
 void make_page_clipbox(struct Page *pg);
 void make_canvas_items(void);
+void make_canvas_item_one(GnomeCanvasGroup *group, struct Item *item);
 void update_canvas_bg(struct Page *pg);
 gboolean is_visible(struct Page *pg);
 void rescale_bg_pixmaps(void);
@@ -30,6 +31,8 @@ void rescale_bg_pixmaps(void);
 gboolean have_intersect(struct BBox *a, struct BBox *b);
 void lower_canvas_item_to(GnomeCanvasGroup *g, GnomeCanvasItem *item, GnomeCanvasItem *after);
 
+void rgb_to_gdkcolor(guint rgba, GdkColor *color);
+
 // interface misc functions
 
 void update_thickness_buttons(void);
@@ -50,9 +53,13 @@ void update_undo_redo_enabled(void);
 void update_copy_paste_enabled(void);
 void update_vbox_order(int *order);
 
+gchar *make_cur_font_name(void);
+void update_font_button(void);
+
 void update_mapping_linkings(int toolno);
 void do_switch_page(int pg, gboolean rescroll, gboolean refresh_all);
 void set_cur_color(int color);
+void recolor_temp_text(int color_no, guint color_rgba);
 void process_color_activate(GtkMenuItem *menuitem, int color);
 void process_thickness_activate(GtkMenuItem *menuitem, int tool, int val);
 void process_papercolor_activate(GtkMenuItem *menuitem, int color);
@@ -61,6 +68,8 @@ void process_paperstyle_activate(GtkMenuItem *menuitem, int style);
 gboolean ok_to_close(void);
 gboolean page_ops_forbidden(void);
 
+void reset_focus(void);
+
 // selection / clipboard stuff
 
 void reset_selection(void);
@@ -72,6 +81,12 @@ void move_journal_items_by(GList *itemlist, double dx, double dy,
 void switch_mapping(int m);
 void process_mapping_activate(GtkMenuItem *menuitem, int m, int tool);
 
+// always allow accels
+void allow_all_accels(void);
+gboolean can_accel(GtkWidget *widget, guint id, gpointer data);
+void add_scroll_bindings(void);
+
+gboolean is_event_within_textview(GdkEventButton *event);
 
 // defines for paper rulings
 
index f52f1240173e4c6143cd05481781dfd71e5b94b6..dd03604c03afeb77cff54d8b6e08997aca1a1df3 100644 (file)
@@ -96,6 +96,9 @@ void update_cursor(void)
   else if (ui.toolno[ui.cur_mapping] == TOOL_HAND) {
     ui.cursor = gdk_cursor_new(GDK_HAND1);
   }
+  else if (ui.toolno[ui.cur_mapping] == TOOL_TEXT) {
+    ui.cursor = gdk_cursor_new(GDK_XTERM);
+  }
   
   gdk_window_set_cursor(GTK_WIDGET(canvas)->window, ui.cursor);
 }
@@ -212,11 +215,7 @@ void finalize_stroke(void)
   // destroy the entire group of temporary line segments
   gtk_object_destroy(GTK_OBJECT(ui.cur_item->canvas_item));
   // make a new line item to replace it
-  ui.cur_item->canvas_item = gnome_canvas_item_new(ui.cur_layer->group, 
-     gnome_canvas_line_get_type(), "points", ui.cur_item->path,
-     "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-     "fill-color-rgba", ui.cur_item->brush.color_rgba,
-     "width-units", ui.cur_item->brush.thickness, NULL);
+  make_canvas_item_one(ui.cur_layer->group, ui.cur_item);
 
   // add undo information
   prepare_new_undo();
@@ -292,11 +291,7 @@ void erase_stroke_portions(struct Item *item, double x, double y, double radius,
       // add the new head
       if (newhead != NULL) {
         update_item_bbox(newhead);
-        newhead->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
-            gnome_canvas_line_get_type(), "points", newhead->path,
-            "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-            "fill-color-rgba", newhead->brush.color_rgba,
-            "width-units", newhead->brush.thickness, NULL);
+        make_canvas_item_one(ui.cur_layer->group, newhead);
         lower_canvas_item_to(ui.cur_layer->group,
                   newhead->canvas_item, erasure->item->canvas_item);
         erasure->replacement_items = g_list_prepend(erasure->replacement_items, newhead);
@@ -315,11 +310,7 @@ void erase_stroke_portions(struct Item *item, double x, double y, double radius,
   // add the tail if needed
   if (!need_recalc) return;
   update_item_bbox(item);
-  item->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
-       gnome_canvas_line_get_type(), "points", item->path,
-       "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-       "fill-color-rgba", item->brush.color_rgba,
-       "width-units", item->brush.thickness, NULL);
+  make_canvas_item_one(ui.cur_layer->group, item);
   lower_canvas_item_to(ui.cur_layer->group, item->canvas_item, 
                                       erasure->item->canvas_item);
 }
@@ -463,10 +454,23 @@ void finalize_selectrect(void)
     }
   }
   
+  if (ui.selection->items == NULL) {
+    // if we clicked inside a text zone ?  
+    item = click_is_in_text(ui.selection->layer, x1, y1);
+    if (item!=NULL && item==click_is_in_text(ui.selection->layer, x2, y2)) {
+      ui.selection->items = g_list_append(ui.selection->items, item);
+      g_memmove(&(ui.selection->bbox), &(item->bbox), sizeof(struct BBox));
+      gnome_canvas_item_set(ui.selection->canvas_item,
+        "x1", item->bbox.left, "x2", item->bbox.right, 
+        "y1", item->bbox.top, "y2", item->bbox.bottom, NULL);
+    }
+  }
+  
   if (ui.selection->items == NULL) reset_selection();
   else make_dashed(ui.selection->canvas_item);
   update_cursor();
   update_copy_paste_enabled();
+  update_font_button();
 }
 
 gboolean start_movesel(GdkEvent *event)
@@ -702,7 +706,7 @@ void callback_clipboard_clear(GtkClipboard *clipboard, gpointer user_data)
 
 void selection_to_clip(void)
 {
-  int bufsz, nitems;
+  int bufsz, nitems, val;
   char *buf, *p;
   GList *list;
   struct Item *item;
@@ -721,6 +725,16 @@ void selection_to_clip(void)
             + sizeof(int) // num_points
             + 2*item->path->num_points*sizeof(double); // the points
     }
+    else if (item->type == ITEM_TEXT) {
+      bufsz+= sizeof(int) // type
+            + sizeof(struct Brush) // brush
+            + 2*sizeof(double) // bbox upper-left
+            + sizeof(int) // text len
+            + strlen(item->text)+1 // text
+            + sizeof(int) // font_name len
+            + strlen(item->font_name)+1 // font_name
+            + sizeof(double); // font_size
+    }
     else bufsz+= sizeof(int); // type
   }
   p = buf = g_malloc(bufsz);
@@ -736,6 +750,18 @@ void selection_to_clip(void)
       g_memmove(p, item->path->coords, 2*item->path->num_points*sizeof(double));
       p+= 2*item->path->num_points*sizeof(double);
     }
+    if (item->type == ITEM_TEXT) {
+      g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
+      g_memmove(p, &item->bbox.left, sizeof(double)); p+= sizeof(double);
+      g_memmove(p, &item->bbox.top, sizeof(double)); p+= sizeof(double);
+      val = strlen(item->text);
+      g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
+      g_memmove(p, item->text, val+1); p+= val+1;
+      val = strlen(item->font_name);
+      g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
+      g_memmove(p, item->font_name, val+1); p+= val+1;
+      g_memmove(p, &item->font_size, sizeof(double)); p+= sizeof(double);
+    }
   }
   
   target.target = "_XOURNAL";
@@ -752,7 +778,7 @@ void clipboard_paste(void)
 {
   GtkSelectionData *sel_data;
   unsigned char *p;
-  int nitems, npts, i;
+  int nitems, npts, i, len;
   GList *list;
   struct Item *item;
   double hoffset, voffset, cx, cy;
@@ -824,11 +850,22 @@ void clipboard_paste(void)
       }
       p+= 2*item->path->num_points*sizeof(double);
       update_item_bbox(item);
-      item->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
-             gnome_canvas_line_get_type(), "points", item->path,
-             "cap-style", GDK_CAP_ROUND, "join-style", GDK_JOIN_ROUND,
-             "fill-color-rgba", item->brush.color_rgba,
-             "width-units", item->brush.thickness, NULL);
+      make_canvas_item_one(ui.cur_layer->group, item);
+    }
+    if (item->type == ITEM_TEXT) {
+      g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
+      g_memmove(&item->bbox.left, p, sizeof(double)); p+= sizeof(double);
+      g_memmove(&item->bbox.top, p, sizeof(double)); p+= sizeof(double);
+      item->bbox.left += hoffset;
+      item->bbox.top += voffset;
+      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
+      item->text = g_malloc(len+1);
+      g_memmove(item->text, p, len+1); p+= len+1;
+      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
+      item->font_name = g_malloc(len+1);
+      g_memmove(item->font_name, p, len+1); p+= len+1;
+      g_memmove(&item->font_size, p, sizeof(double)); p+= sizeof(double);
+      make_canvas_item_one(ui.cur_layer->group, item);
     }
   }
 
@@ -856,7 +893,8 @@ void recolor_selection(int color)
   undo->auxlist = NULL;
   for (itemlist = ui.selection->items; itemlist!=NULL; itemlist = itemlist->next) {
     item = (struct Item *)itemlist->data;
-    if (item->type != ITEM_STROKE || item->brush.tool_type!=TOOL_PEN) continue;
+    if (item->type != ITEM_STROKE && item->type != ITEM_TEXT) continue;
+    if (item->type == ITEM_STROKE && item->brush.tool_type!=TOOL_PEN) continue;
     // store info for undo
     undo->itemlist = g_list_append(undo->itemlist, item);
     brush = (struct Brush *)g_malloc(sizeof(struct Brush));
@@ -899,14 +937,276 @@ void rethicken_selection(int val)
   }
 }
 
+gboolean do_hand_scrollto(gpointer data)
+{
+  ui.hand_scrollto_pending = FALSE;
+  gnome_canvas_scroll_to(canvas, ui.hand_scrollto_cx, ui.hand_scrollto_cy);
+  return FALSE;
+}
+
 void do_hand(GdkEvent *event)
 {
-  double pt[2], val;
+  double pt[2];
   int cx, cy;
   
   get_pointer_coords(event, pt);
   gnome_canvas_get_scroll_offsets(canvas, &cx, &cy);
-  cx -= (pt[0]-ui.hand_refpt[0])*ui.zoom;
-  cy -= (pt[1]-ui.hand_refpt[1])*ui.zoom;
-  gnome_canvas_scroll_to(canvas, cx, cy);
+  ui.hand_scrollto_cx = cx - (pt[0]-ui.hand_refpt[0])*ui.zoom;
+  ui.hand_scrollto_cy = cy - (pt[1]-ui.hand_refpt[1])*ui.zoom;
+  if (!ui.hand_scrollto_pending) g_idle_add(do_hand_scrollto, NULL);
+  ui.hand_scrollto_pending = TRUE;
+}
+
+/************ TEXT FUNCTIONS **************/
+
+// to make it easier to copy/paste at end of text box
+#define WIDGET_RIGHT_MARGIN 10
+
+void resize_textview(gpointer *toplevel, gpointer *data)
+{
+  GtkTextView *w;
+  int width, height;
+  
+  /* when the text changes, resize the GtkTextView accordingly */
+  if (ui.cur_item_type!=ITEM_TEXT) return;
+  w = GTK_TEXT_VIEW(ui.cur_item->widget);
+  width = w->width + WIDGET_RIGHT_MARGIN;
+  height = w->height;
+  gnome_canvas_item_set(ui.cur_item->canvas_item, 
+    "size-pixels", TRUE, 
+    "width", (gdouble)width, "height", (gdouble)height, NULL);
+  ui.cur_item->bbox.right = ui.cur_item->bbox.left + width/ui.zoom;
+  ui.cur_item->bbox.bottom = ui.cur_item->bbox.top + height/ui.zoom;
+}
+
+void start_text(GdkEvent *event, struct Item *item)
+{
+  double pt[2];
+  gchar *text;
+  GtkTextBuffer *buffer;
+  GnomeCanvasItem *canvas_item;
+  PangoFontDescription *font_desc;
+  GdkColor color;
+  
+  get_pointer_coords(event, pt);
+  ui.cur_item_type = ITEM_TEXT;
+
+  if (item==NULL) {
+    item = g_new(struct Item, 1);
+    item->text = NULL;
+    item->canvas_item = NULL;
+    item->bbox.left = pt[0];
+    item->bbox.top = pt[1];
+    item->bbox.right = ui.cur_page->width;
+    item->bbox.bottom = pt[1]+100.;
+    item->font_name = g_strdup(ui.font_name);
+    item->font_size = ui.font_size;
+    g_memmove(&(item->brush), ui.cur_brush, sizeof(struct Brush));
+    ui.cur_layer->items = g_list_append(ui.cur_layer->items, item);
+    ui.cur_layer->nitems++;
+  }
+  
+  item->type = ITEM_TEMP_TEXT;
+  ui.cur_item = item;
+  
+  font_desc = pango_font_description_from_string(item->font_name);
+  pango_font_description_set_absolute_size(font_desc, 
+      item->font_size*ui.zoom*PANGO_SCALE);
+  item->widget = gtk_text_view_new();
+  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(item->widget));
+  if (item->text!=NULL)
+    gtk_text_buffer_set_text(buffer, item->text, -1);
+  gtk_widget_modify_font(item->widget, font_desc);
+  rgb_to_gdkcolor(item->brush.color_rgba, &color);
+  gtk_widget_modify_text(item->widget, GTK_STATE_NORMAL, &color);
+  pango_font_description_free(font_desc);
+
+  canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
+    gnome_canvas_widget_get_type(),
+    "x", item->bbox.left, "y", item->bbox.top, 
+    "width", item->bbox.right-item->bbox.left, 
+    "height", item->bbox.bottom-item->bbox.top,
+    "widget", item->widget, NULL);
+  // TODO: width/height?
+  if (item->canvas_item!=NULL) {
+    lower_canvas_item_to(ui.cur_layer->group, canvas_item, item->canvas_item);
+    gtk_object_destroy(GTK_OBJECT(item->canvas_item));
+  }
+  item->canvas_item = canvas_item;
+
+  gtk_widget_show(item->widget);
+  gtk_widget_grab_focus(item->widget);
+  ui.resize_signal_handler = 
+    g_signal_connect((gpointer) winMain, "check_resize",
+       G_CALLBACK(resize_textview), NULL);
+  update_font_button();
+  gtk_widget_set_sensitive(GET_COMPONENT("editPaste"), FALSE);
+  gtk_widget_set_sensitive(GET_COMPONENT("buttonPaste"), FALSE);
+}
+
+void end_text(void)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter start, end;
+  gchar *new_text;
+  struct UndoErasureData *erasure;
+  GnomeCanvasItem *tmpitem;
+
+  if (ui.cur_item_type!=ITEM_TEXT) return; // nothing for us to do!
+  
+  // finalize the text that's been edited... 
+  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(ui.cur_item->widget));
+  gtk_text_buffer_get_bounds(buffer, &start, &end);
+  ui.cur_item->type = ITEM_TEXT;
+  new_text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE);
+  ui.cur_item_type = ITEM_NONE;
+  gtk_widget_set_sensitive(GET_COMPONENT("editPaste"), TRUE);
+  gtk_widget_set_sensitive(GET_COMPONENT("buttonPaste"), TRUE);
+  
+  if (strlen(new_text)==0) { // erase object and cancel
+    g_free(new_text);
+    g_signal_handler_disconnect(winMain, ui.resize_signal_handler);
+    gtk_object_destroy(GTK_OBJECT(ui.cur_item->canvas_item));
+    ui.cur_item->canvas_item = NULL;
+    if (ui.cur_item->text == NULL) // nothing happened
+      g_free(ui.cur_item->font_name);
+    else { // treat this as an erasure
+      prepare_new_undo();
+      undo->type = ITEM_ERASURE;
+      undo->layer = ui.cur_layer;
+      erasure = (struct UndoErasureData *)g_malloc(sizeof(struct UndoErasureData));
+      erasure->item = ui.cur_item;
+      erasure->npos = g_list_index(ui.cur_layer->items, ui.cur_item);
+      erasure->nrepl = 0;
+      erasure->replacement_items = NULL;
+      undo->erasurelist = g_list_append(NULL, erasure);
+    }
+    ui.cur_layer->items = g_list_remove(ui.cur_layer->items, ui.cur_item);
+    ui.cur_layer->nitems--;
+    ui.cur_item = NULL;
+    return;
+  }
+
+  // store undo data
+  if (ui.cur_item->text==NULL || strcmp(ui.cur_item->text, new_text)) {
+    prepare_new_undo();
+    if (ui.cur_item->text == NULL) undo->type = ITEM_TEXT; 
+    else undo->type = ITEM_TEXT_EDIT;
+    undo->layer = ui.cur_layer;
+    undo->item = ui.cur_item;
+    undo->str = ui.cur_item->text;
+  }
+  else g_free(ui.cur_item->text);
+
+  ui.cur_item->text = new_text;
+  ui.cur_item->widget = NULL;
+  // replace the canvas item
+  tmpitem = ui.cur_item->canvas_item;
+  make_canvas_item_one(ui.cur_layer->group, ui.cur_item);
+  update_item_bbox(ui.cur_item);
+  lower_canvas_item_to(ui.cur_layer->group, ui.cur_item->canvas_item, tmpitem);
+  gtk_object_destroy(GTK_OBJECT(tmpitem));
+}
+
+/* update the items in the canvas so they're of the right font size */
+
+void update_text_item_displayfont(struct Item *item)
+{
+  PangoFontDescription *font_desc;
+
+  if (item->type != ITEM_TEXT && item->type != ITEM_TEMP_TEXT) return;
+  if (item->canvas_item==NULL) return;
+  font_desc = pango_font_description_from_string(item->font_name);
+  pango_font_description_set_absolute_size(font_desc, 
+        item->font_size*ui.zoom*PANGO_SCALE);
+  if (item->type == ITEM_TEMP_TEXT)
+    gtk_widget_modify_font(item->widget, font_desc);
+  else {
+    gnome_canvas_item_set(item->canvas_item, "font-desc", font_desc, NULL);
+    update_item_bbox(item);
+  }
+  pango_font_description_free(font_desc);
+}
+
+void rescale_text_items(void)
+{
+  GList *pagelist, *layerlist, *itemlist;
+  struct Layer *l;
+  
+  for (pagelist = journal.pages; pagelist!=NULL; pagelist = pagelist->next)
+    for (layerlist = ((struct Page *)pagelist->data)->layers; layerlist!=NULL; layerlist = layerlist->next)
+      for (itemlist = ((struct Layer *)layerlist->data)->items; itemlist!=NULL; itemlist = itemlist->next)
+        update_text_item_displayfont((struct Item *)itemlist->data);
+}
+
+struct Item *click_is_in_text(struct Layer *layer, double x, double y)
+{
+  GList *itemlist;
+  struct Item *item, *val;
+  
+  val = NULL;
+  for (itemlist = layer->items; itemlist!=NULL; itemlist = itemlist->next) {
+    item = (struct Item *)itemlist->data;
+    if (item->type != ITEM_TEXT) continue;
+    if (x<item->bbox.left || x>item->bbox.right) continue;
+    if (y<item->bbox.top || y>item->bbox.bottom) continue;
+    val = item;
+  }
+  return val;
+}
+
+void refont_text_item(struct Item *item, gchar *font_name, double font_size)
+{
+  if (!strcmp(font_name, item->font_name) && font_size==item->font_size) return;
+  if (item->text!=NULL) {
+    prepare_new_undo();
+    undo->type = ITEM_TEXT_ATTRIB;
+    undo->item = item;
+    undo->str = item->font_name;
+    undo->val_x = item->font_size;
+    undo->brush = (struct Brush *)g_memdup(&(item->brush), sizeof(struct Brush));
+  }
+  else g_free(item->font_name);
+  item->font_name = g_strdup(font_name);
+  if (font_size>0.) item->font_size = font_size;
+  update_text_item_displayfont(item);
+}
+
+void process_font_sel(gchar *str)
+{
+  gchar *p, *q;
+  struct Item *it;
+  gdouble size;
+  GList *list;
+  gboolean undo_cont;
+
+  p = strrchr(str, ' ');
+  if (p!=NULL) { 
+    size = g_strtod(p+1, &q);
+    if (*q!=0 || size<1.) size=0.;
+    else *p=0;
+  }
+  else size=0.;
+  reset_focus();
+  g_free(ui.font_name);
+  ui.font_name = str;  
+  if (size>0.) ui.font_size = size;
+  undo_cont = FALSE;   
+  // if there's a current text item, re-font it
+  if (ui.cur_item_type == ITEM_TEXT) {
+    refont_text_item(ui.cur_item, str, size);
+    undo_cont = (ui.cur_item->text!=NULL);   
+  }
+  // if there's a current selection, re-font it
+  if (ui.selection!=NULL) 
+    for (list=ui.selection->items; list!=NULL; list=list->next) {
+      it = (struct Item *)list->data;
+      if (it->type == ITEM_TEXT) {   
+        if (undo_cont) undo->multiop |= MULTIOP_CONT_REDO;
+        refont_text_item(it, str, size);
+        if (undo_cont) undo->multiop |= MULTIOP_CONT_UNDO;
+        undo_cont = TRUE;
+      }
+    }  
+  update_font_button();
 }
index d01cee294b1ef36432f0c9d5d6c770ddcffccff4..4799a7e5fdeefd738896fe8156e4ce2cebd15775 100644 (file)
@@ -22,3 +22,16 @@ void clipboard_paste(void);
 
 void recolor_selection(int color);
 void rethicken_selection(int val);
+
+/* text functions */
+
+#define DEFAULT_FONT "Sans"
+#define DEFAULT_FONT_SIZE 12
+
+void start_text(GdkEvent *event, struct Item *item);
+void end_text(void);
+void update_text_item_displayfont(struct Item *item);
+void rescale_text_items(void);
+struct Item *click_is_in_text(struct Layer *layer, double x, double y);
+void refont_text_item(struct Item *item, gchar *font_name, double font_size);
+void process_font_sel(gchar *str);
index cc2d4c150643a12a2e93f3a1d1618d6821f24f05..cfd61e1f0b3ce53207c2a17d49e61f1a1c874e32 100644 (file)
@@ -2,12 +2,21 @@
 #  include <config.h>
 #endif
 
+#define PANGO_ENABLE_BACKEND /* to access PangoFcFont.font_pattern */
+
 #include <gtk/gtk.h>
 #include <libgnomecanvas/libgnomecanvas.h>
 #include <libgnomeprint/gnome-print-job.h>
+#include <libgnomeprint/gnome-print-pango.h>
 #include <zlib.h>
 #include <string.h>
 #include <locale.h>
+#include <pango/pango.h>
+#include <pango/pangofc-font.h>
+#include <fontconfig/fontconfig.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include "sft.h" /* Sun Font Tools, embedded in libgnomeprint */
 
 #include "xournal.h"
 #include "xo-misc.h"
@@ -531,8 +540,9 @@ GString *make_pdfprefix(struct PdfPageDesc *pgdesc, double width, double height)
   GString *str;
   double v[4], t, xscl, yscl;
   int i;
-  
-  str = g_string_new("q ");
+
+  // push 3 times in case code to be annotated has unbalanced q/Q (B of A., ...)
+  str = g_string_new("q q q "); 
   if (pgdesc->rotate == 90) {
     g_string_append_printf(str, "0 -1 1 0 0 %.2f cm ", height);
     t = height; height = width; width = t;
@@ -752,20 +762,278 @@ int pdf_draw_bitmap_background(struct Page *pg, GString *str,
   return xref->last;
 }
 
+// manipulate Pdf fonts
+
+struct PdfFont *new_pdffont(struct XrefTable *xref, GList **fonts,
+   unsigned char *filename, int font_id, FT_Face face, int glyph_page)
+{
+  GList *list;
+  struct PdfFont *font;
+  int i;
+  const char *s;
+  
+  for (list = *fonts; list!=NULL; list = list->next) {
+    font = (struct PdfFont *)list->data;
+    if (!strcmp(font->filename, filename) && font->font_id == font_id 
+        && font->glyph_page == glyph_page)
+          { font->used_in_this_page = TRUE; return font; }
+  }
+  font = g_malloc(sizeof(struct PdfFont));
+  *fonts = g_list_append(*fonts, font);
+  font->n_obj = xref->last+1;
+  make_xref(xref, xref->last+1, 0); // will give it a value later
+  font->filename = g_strdup(filename);
+  font->font_id = font_id;
+  font->glyph_page = glyph_page;
+  font->used_in_this_page = TRUE;
+  font->num_glyphs_used = 0;
+  for (i=0; i<256; i++) {
+    font->glyphmap[i] = -1;
+    font->advance[i] = 0;
+    font->glyphpsnames[i] = NULL;
+  }
+  font->glyphmap[0] = 0;
+  // fill in info from the FT_Face
+  font->is_truetype = FT_IS_SFNT(face);
+  font->nglyphs = face->num_glyphs;
+  font->ft2ps = 1000.0 / face->units_per_EM;
+  font->ascender = (int)(font->ft2ps*face->ascender);
+  font->descender = (int)(font->ft2ps*face->descender);
+  if (face->bbox.xMin < -100000 || face->bbox.xMin > 100000) font->xmin = 0;
+  else font->xmin = (int)(font->ft2ps*face->bbox.xMin);
+  if (face->bbox.xMax < -100000 || face->bbox.xMax > 100000) font->xmax = 0;
+  else font->xmax = (int)(font->ft2ps*face->bbox.xMax);
+  if (face->bbox.yMin < -100000 || face->bbox.yMin > 100000) font->ymin = 0;
+  else font->ymin = (int)(font->ft2ps*face->bbox.yMin);
+  if (face->bbox.yMax < -100000 || face->bbox.yMax > 100000) font->ymax = 0;
+  else font->ymax = (int)(font->ft2ps*face->bbox.yMax);
+  if (font->is_truetype) font->flags = 4; // symbolic
+  else {
+    font->flags = 4; // symbolic
+    if (FT_IS_FIXED_WIDTH(face)) font->flags |= 1;
+    if (face->style_flags & FT_STYLE_FLAG_ITALIC) font->flags |= 64;
+  }
+  s = FT_Get_Postscript_Name(face);
+  if (s==NULL) s = "Noname";
+  if (glyph_page) font->fontname = g_strdup_printf("%s_%03d", s, glyph_page);
+  else font->fontname = g_strdup(s);
+  return font;
+}
+
+#define pfb_get_length(x) (((x)[3]<<24) + ((x)[2]<<16) + ((x)[1]<<8) + (x)[0])
+#define T1_SEGMENT_1_END "currentfile eexec"
+#define T1_SEGMENT_3_END "cleartomark"
+
+void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font)
+{
+  // this code inspired by libgnomeprint
+  gboolean fallback, is_binary;
+  guchar encoding[256];
+  gushort glyphs[256];
+  int i, j, num, len, len1, len2;
+  TrueTypeFont *ttfnt;
+  char *tmpfile, *seg1, *seg2;
+  unsigned char *fontdata, *p;
+  char prefix[8];
+  int nobj_fontprog, nobj_descr, lastchar;
+  
+  fallback = FALSE;
+  // embed the font file: TrueType case
+  if (font->is_truetype) {
+    glyphs[0] = encoding[0] = 0;
+    num = 1;
+    for (i=1; i<=255; i++) 
+      if (font->glyphmap[i]>=0) {
+        font->glyphmap[i] = num;
+        glyphs[num] = 255*font->glyph_page+i-1;
+        encoding[num] = i;
+        num++;
+      }
+    font->num_glyphs_used = num-1;
+    if (OpenTTFont(font->filename, 0, &ttfnt) == SF_OK) {
+      tmpfile = mktemp(g_strdup(TMPDIR_TEMPLATE));
+      CreateTTFromTTGlyphs(ttfnt, tmpfile, glyphs, encoding, num, 
+                           0, NULL, TTCF_AutoName | TTCF_IncludeOS2);
+      CloseTTFont(ttfnt);
+      if (g_file_get_contents(tmpfile, (char **)&fontdata, &len, NULL) && len>=8) {
+        make_xref(xref, xref->last+1, pdfbuf->len);
+        nobj_fontprog = xref->last;
+        g_string_append_printf(pdfbuf, 
+          "%d 0 obj\n<< /Length %d /Length1 %d >> stream\n",
+          nobj_fontprog, len, len);
+        g_string_append_len(pdfbuf, fontdata, len);
+        g_string_append(pdfbuf, "endstream\nendobj\n");
+        g_free(fontdata);
+      } 
+      else fallback = TRUE;
+      unlink(tmpfile);
+      g_free(tmpfile);
+    }
+    else fallback = TRUE;  
+  } else {
+  // embed the font file: Type1 case
+    if (g_file_get_contents(font->filename, (char **)&fontdata, &len, NULL) && len>=8) {
+      if (fontdata[0]==0x80 && fontdata[1]==0x01) {
+        is_binary = TRUE;
+        len1 = pfb_get_length(fontdata+2);
+        if (fontdata[len1+6]!=0x80 || fontdata[len1+7]!=0x02) fallback = TRUE;
+        else {
+          len2 = pfb_get_length(fontdata+len1+8);
+          if (fontdata[len1+len2+12]!=0x80 || fontdata[len1+len2+13]!=0x01)
+            fallback = TRUE;
+        }
+      }
+      else if (!strncmp(fontdata, "%!PS", 4)) {
+        is_binary = FALSE;
+        p = strstr(fontdata, T1_SEGMENT_1_END) + strlen(T1_SEGMENT_1_END);
+        if (p==NULL) fallback = TRUE;
+        else {
+          if (*p=='\n' || *p=='\r') p++;
+          if (*p=='\n' || *p=='\r') p++;
+          len1 = p-fontdata;
+          p = g_strrstr_len(fontdata, len, T1_SEGMENT_3_END);
+          if (p==NULL) fallback = TRUE;
+          else {
+            // rewind 512 zeros
+            i = 512; p--;
+            while (i>0 && p!=fontdata && (*p=='0' || *p=='\r' || *p=='\n')) {
+              if (*p=='0') i--;
+              p--;
+            }
+            while (p!=fontdata && (*p=='\r' || *p=='\n')) p--;
+            p++;
+            if (i>0) fallback = TRUE;
+            else len2 = p-fontdata-len1;
+          }
+        }
+      }
+      else fallback = TRUE;
+      if (!fallback) {
+        if (is_binary) {
+          seg1 = fontdata+6;
+          seg2 = fontdata + len1 + 12;
+        } else {
+          seg1 = fontdata;
+          seg2 = g_malloc(len2/2);
+          j=0;
+          p = fontdata+len1;
+          while (p+1 < fontdata+len1+len2) {
+            if (*p==' '||*p=='\t'||*p=='\n'||*p=='\r') { p++; continue; }
+            if (p[0]>'9') { p[0]|=0x20; p[0]-=39; }
+            if (p[1]>'9') { p[1]|=0x20; p[1]-=39; }
+            seg2[j++] = ((p[0]-'0')<<4) + (p[1]-'0');
+            p+=2;
+          }
+          len2 = j;
+        }
+        make_xref(xref, xref->last+1, pdfbuf->len);
+        nobj_fontprog = xref->last;
+        g_string_append_printf(pdfbuf, 
+          "%d 0 obj\n<< /Length %d /Length1 %d /Length2 %d /Length3 0 >> stream\n",
+          nobj_fontprog, len1+len2, len1, len2);
+        g_string_append_len(pdfbuf, seg1, len1);
+        g_string_append_len(pdfbuf, seg2, len2);
+        g_string_append(pdfbuf, "endstream\nendobj\n");
+        if (!is_binary) g_free(seg2);
+      }
+      g_free(fontdata);
+    }
+    else fallback = TRUE;
+  }
+  
+  // next, the font descriptor
+  if (!fallback) {
+    make_xref(xref, xref->last+1, pdfbuf->len);
+    nobj_descr = xref->last;
+    g_string_append_printf(pdfbuf,
+      "%d 0 obj\n<< /Type /FontDescriptor /FontName /%s /Flags %d "
+      "/FontBBox [%d %d %d %d] /ItalicAngle 0 /Ascent %d "
+      "/Descent %d /CapHeight %d /StemV 100 /%s %d 0 R >> endobj\n",
+      nobj_descr, font->fontname, font->flags, 
+      font->xmin, font->ymin, font->xmax, font->ymax, 
+      font->ascender, -font->descender, font->ascender, 
+      font->is_truetype ? "FontFile2":"FontFile",
+      nobj_fontprog);
+  }
+  
+  // finally, the font itself
+  /* Note: in Type1 case, font->glyphmap maps charcodes to glyph no's
+     in TrueType case, encoding lists the used charcodes by index,
+                       glyphs   list the used glyph no's by index
+                       font->glyphmap maps charcodes to indices        */
+  xref->data[font->n_obj] = pdfbuf->len;
+  if (font->is_truetype) lastchar = encoding[font->num_glyphs_used];
+  else lastchar = font->num_glyphs_used;
+  if (fallback) {
+    font->is_truetype = FALSE;
+    g_free(font->fontname);
+    font->fontname = g_strdup("Helvetica");
+  }
+  prefix[0]=0;
+  if (font->is_truetype) {
+    num = font->glyph_page;
+    for (i=0; i<6; i++) { prefix[i] = 'A'+(num%26); num/=26; }
+    prefix[6]='+'; prefix[7]=0;
+  }
+  g_string_append_printf(pdfbuf,
+    "%d 0 obj\n<< /Type /Font /Subtype /%s /BaseFont /%s%s /Name /F%d ",
+    font->n_obj, font->is_truetype?"TrueType":"Type1",
+    prefix, font->fontname, font->n_obj);
+  if (!fallback) {
+    g_string_append_printf(pdfbuf,
+      "/FontDescriptor %d 0 R /FirstChar 0 /LastChar %d /Widths [",
+      nobj_descr, lastchar);
+    for (i=0; i<=lastchar; i++)
+      g_string_append_printf(pdfbuf, "%d ", font->advance[i]);
+    g_string_append(pdfbuf, "] ");
+  }
+  if (!font->is_truetype) { /* encoding */
+    g_string_append(pdfbuf, "/Encoding << /Type /Encoding "
+      "/BaseEncoding /MacRomanEncoding /Differences [1 ");
+    for (i=1; i<=lastchar; i++) {
+      g_string_append_printf(pdfbuf, "/%s ", font->glyphpsnames[i]);
+      g_free(font->glyphpsnames[i]);
+    }
+    g_string_append(pdfbuf, "] >> ");
+  }
+  g_string_append(pdfbuf, ">> endobj\n");
+}
+
 // draw a page's graphics
 
-void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter)
+void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, 
+                  struct XrefTable *xref, GList **pdffonts)
 {
-  GList *layerlist, *itemlist;
+  GList *layerlist, *itemlist, *tmplist;
   struct Layer *l;
   struct Item *item;
-  guint old_rgba;
+  guint old_rgba, old_text_rgba;
   double old_thickness;
   double *pt;
-  int i;
+  int i, j;
+  PangoFontDescription *font_desc;
+  PangoContext *context;
+  PangoLayout *layout;
+  PangoLayoutIter *iter;
+  PangoRectangle logical_rect;
+  PangoLayoutRun *run;
+  PangoFcFont *fcfont;
+  FcPattern *pattern;
+  int baseline, advance;
+  int glyph_no, glyph_page, current_page;
+  unsigned char *filename;
+  char tmpstr[200];
+  int font_id;
+  FT_Face ftface;
+  struct PdfFont *cur_font;
+  gboolean in_string;
   
-  old_rgba = 0x12345678;    // not any values we use, so we'll reset them
+  old_rgba = old_text_rgba = 0x12345678;    // not any values we use, so we'll reset them
   old_thickness = 0.0;
+  for (tmplist = *pdffonts; tmplist!=NULL; tmplist = tmplist->next) {
+    cur_font = (struct PdfFont *)tmplist->data;
+    cur_font->used_in_this_page = FALSE;
+  }
 
   for (layerlist = pg->layers; layerlist!=NULL; layerlist = layerlist->next) {
     l = (struct Layer *)layerlist->data;
@@ -791,6 +1059,88 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter)
         if ((item->brush.color_rgba & 0xf0) != 0xf0) // undo transparent
           g_string_append(str, "Q ");
       }
+      else if (item->type == ITEM_TEXT) {
+        if ((item->brush.color_rgba & ~0xff) != old_text_rgba)
+          g_string_append_printf(str, "%.2f %.2f %.2f rg ",
+            RGBA_RGB(item->brush.color_rgba));
+        old_text_rgba = item->brush.color_rgba & ~0xff;
+        context = gnome_print_pango_create_context(gnome_print_pango_get_default_font_map());
+        layout = pango_layout_new(context);
+        g_object_unref(context);
+        font_desc = pango_font_description_from_string(item->font_name);
+        pango_font_description_set_absolute_size(font_desc,
+          item->font_size*PANGO_SCALE);
+        pango_layout_set_font_description(layout, font_desc);
+        pango_font_description_free(font_desc);
+        pango_layout_set_text(layout, item->text, -1);
+        // this code inspired by the code in libgnomeprint
+        iter = pango_layout_get_iter(layout);
+        do {
+          run = pango_layout_iter_get_run(iter);
+          if (run==NULL) continue;
+          pango_layout_iter_get_run_extents (iter, NULL, &logical_rect);
+          baseline = pango_layout_iter_get_baseline (iter);
+          if (!PANGO_IS_FC_FONT(run->item->analysis.font)) continue;
+          fcfont = PANGO_FC_FONT(run->item->analysis.font);
+          pattern = fcfont->font_pattern;
+          if (FcPatternGetString(pattern, FC_FILE, 0, &filename) != FcResultMatch ||
+              FcPatternGetInteger(pattern, FC_INDEX, 0, &font_id) != FcResultMatch)
+                continue;
+          ftface = pango_fc_font_lock_face(fcfont);
+          current_page = -1;
+          cur_font = NULL;
+          g_string_append_printf(str, "BT %.2f 0 0 %.2f %.2f %.2f Tm ",
+            item->font_size, -item->font_size,
+            item->bbox.left + (gdouble) logical_rect.x/PANGO_SCALE,
+            item->bbox.top + (gdouble) baseline/PANGO_SCALE);
+          in_string = FALSE;
+          for (i=0; i<run->glyphs->num_glyphs; i++) {
+            glyph_no = run->glyphs->glyphs[i].glyph;
+            if (FT_IS_SFNT(ftface)) glyph_page = glyph_no/255;
+            else glyph_page = 0;
+            if (glyph_page != current_page) {
+              cur_font = new_pdffont(xref, pdffonts, filename, font_id,
+                 ftface, glyph_page);
+              if (in_string) g_string_append(str, ") Tj ");
+              in_string = FALSE;
+              g_string_append_printf(str, "/F%d 1 Tf ", cur_font->n_obj);
+            }
+            current_page = glyph_page;
+            FT_Load_Glyph(ftface, glyph_no, FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
+            advance = (int)(ftface->glyph->metrics.horiAdvance * cur_font->ft2ps + 0.5);
+            if (!in_string) g_string_append_c(str, '(');
+            in_string = TRUE;
+            if (cur_font->is_truetype) {
+              if (glyph_no) glyph_no = (glyph_no%255)+1;
+              cur_font->glyphmap[glyph_no] = glyph_no;
+            }
+            else {
+              for (j=1; j<=cur_font->num_glyphs_used; j++)
+                if (cur_font->glyphmap[j] == glyph_no) break;
+              if (j==256) j=0; // font is full, what do we do?
+              if (j>cur_font->num_glyphs_used) {
+                cur_font->glyphmap[j] = glyph_no; 
+                cur_font->num_glyphs_used++;
+                if (FT_Get_Glyph_Name(ftface, glyph_no, tmpstr, 200) == FT_Err_Ok)
+                  cur_font->glyphpsnames[j] = g_strdup(tmpstr);
+                else cur_font->glyphpsnames[j] = g_strdup(".notdef");
+              }
+              glyph_no = j;
+            }
+            cur_font->advance[glyph_no] = advance;
+            if (glyph_no=='\\' || glyph_no == '(' || glyph_no == ')' || glyph_no == 10 || glyph_no == 13) 
+              g_string_append_c(str, '\\');
+            if (glyph_no==10) g_string_append_c(str,'n');
+            else if (glyph_no==13) g_string_append_c(str,'r');
+            else g_string_append_c(str, glyph_no);
+          }
+          if (in_string) g_string_append(str, ") Tj ");
+          g_string_append(str, "ET ");
+          pango_fc_font_unlock_face(fcfont);
+        } while (pango_layout_iter_next_run(iter));
+        pango_layout_iter_free(iter);
+        g_object_unref(layout);
+      }
     }
   }
 }
@@ -819,6 +1169,9 @@ gboolean print_to_pdf(char *filename)
   gboolean use_hiliter;
   struct PdfInfo pdfinfo;
   struct PdfObj *obj;
+  GList *pdffonts, *list;
+  struct PdfFont *font;
+  char *tmpbuf;
   
   f = fopen(filename, "w");
   if (f == NULL) return FALSE;
@@ -826,6 +1179,7 @@ gboolean print_to_pdf(char *filename)
   annot = FALSE;
   xref.data = NULL;
   uses_pdf = FALSE;
+  pdffonts = NULL;
   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
     pg = (struct Page *)pglist->data;
     if (pg->bg->type == BG_PDF) uses_pdf = TRUE;
@@ -866,8 +1220,8 @@ gboolean print_to_pdf(char *filename)
   g_string_append_printf(pdfbuf, "] /Count %d >> endobj\n", journal.npages);
   make_xref(&xref, n_obj_catalog+2, pdfbuf->len);
   g_string_append_printf(pdfbuf, 
-    "%d 0 obj\n<< /Type /ExtGState /CA 0.5 >> endobj\n",
-     n_obj_catalog+2);
+    "%d 0 obj\n<< /Type /ExtGState /CA %.2f >> endobj\n",
+     n_obj_catalog+2, ui.hiliter_opacity);
   xref.last = n_obj_pages_offs + journal.npages-1;
   
   for (pglist = journal.pages, n_page = 0; pglist!=NULL;
@@ -891,13 +1245,13 @@ gboolean print_to_pdf(char *filename)
         "%d 0 obj\n<< /Length %d >> stream\n%s\nendstream\nendobj\n",
         n_obj_prefix, tmpstr->len, tmpstr->str);
       g_string_free(tmpstr, TRUE);
-      g_string_prepend(pgstrm, "Q ");
+      g_string_prepend(pgstrm, "Q Q Q ");
     }
     else if (pg->bg->type == BG_PIXMAP || pg->bg->type == BG_PDF)
       n_obj_bgpix = pdf_draw_bitmap_background(pg, pgstrm, &xref, pdfbuf);
     // draw the page contents
     use_hiliter = FALSE;
-    pdf_draw_page(pg, pgstrm, &use_hiliter);
+    pdf_draw_page(pg, pgstrm, &use_hiliter, &xref, &pdffonts);
     g_string_append_printf(pgstrm, "Q\n");
     
     // deflate pgstrm and write it
@@ -962,11 +1316,32 @@ gboolean print_to_pdf(char *filename)
     if (n_obj_bgpix>0)
       add_dict_subentry(pdfbuf, &xref,
         obj, "/XObject", PDFTYPE_DICT, "/ImBg", mk_pdfref(n_obj_bgpix));
+    for (list=pdffonts; list!=NULL; list = list->next) {
+      font = (struct PdfFont *)list->data;
+      if (font->used_in_this_page) {
+        add_dict_subentry(pdfbuf, &xref,
+          obj, "/ProcSet", PDFTYPE_ARRAY, NULL, mk_pdfname("/Text"));
+        tmpbuf = g_strdup_printf("/F%d", font->n_obj);
+        add_dict_subentry(pdfbuf, &xref,
+          obj, "/Font", PDFTYPE_DICT, tmpbuf, mk_pdfref(font->n_obj));
+        g_free(tmpbuf);
+      }
+    }
     show_pdfobj(obj, pdfbuf);
     free_pdfobj(obj);
     g_string_append(pdfbuf, " >> endobj\n");
   }
   
+  // after the pages, we insert fonts
+  for (list = pdffonts; list!=NULL; list = list->next) {
+    font = (struct PdfFont *)list->data;
+    embed_pdffont(pdfbuf, &xref, font);
+    g_free(font->filename);
+    g_free(font->fontname);
+    g_free(font);
+  }
+  g_list_free(pdffonts);
+  
   // PDF trailer
   startxref = pdfbuf->len;
   if (annot) g_string_append_printf(pdfbuf,
@@ -1027,7 +1402,7 @@ void print_background(GnomePrintContext *gpc, struct Page *pg, gboolean *abort)
   if (pg->bg->type == BG_SOLID) {
     gnome_print_setopacity(gpc, 1.0);
     gnome_print_setrgbcolor(gpc, RGBA_RGB(pg->bg->color_rgba));
-    gnome_print_rect_filled(gpc, 0, 0, pg->width, pg->height);
+    gnome_print_rect_filled(gpc, 0, 0, pg->width, -pg->height);
 
     if (!ui.print_ruling) return;
     if (pg->bg->ruling == RULING_NONE) return;
@@ -1036,17 +1411,17 @@ void print_background(GnomePrintContext *gpc, struct Page *pg, gboolean *abort)
     
     if (pg->bg->ruling == RULING_GRAPH) {
       for (x=RULING_GRAPHSPACING; x<pg->width-1; x+=RULING_GRAPHSPACING)
-        gnome_print_line_stroked(gpc, x, 0, x, pg->height);
+        gnome_print_line_stroked(gpc, x, 0, x, -pg->height);
       for (y=RULING_GRAPHSPACING; y<pg->height-1; y+=RULING_GRAPHSPACING)
-        gnome_print_line_stroked(gpc, 0, y, pg->width, y);
+        gnome_print_line_stroked(gpc, 0, -y, pg->width, -y);
       return;
     }
     
     for (y=RULING_TOPMARGIN; y<pg->height-1; y+=RULING_SPACING)
-      gnome_print_line_stroked(gpc, 0, y, pg->width, y);
+      gnome_print_line_stroked(gpc, 0, -y, pg->width, -y);
     if (pg->bg->ruling == RULING_LINED) {
       gnome_print_setrgbcolor(gpc, RGBA_RGB(RULING_MARGIN_COLOR));
-      gnome_print_line_stroked(gpc, RULING_LEFTMARGIN, 0, RULING_LEFTMARGIN, pg->height);
+      gnome_print_line_stroked(gpc, RULING_LEFTMARGIN, 0, RULING_LEFTMARGIN, -pg->height);
     }
     return;
   }
@@ -1067,7 +1442,7 @@ void print_background(GnomePrintContext *gpc, struct Page *pg, gboolean *abort)
     if (gdk_pixbuf_get_bits_per_sample(pix) != 8) return;
     if (gdk_pixbuf_get_colorspace(pix) != GDK_COLORSPACE_RGB) return;
     gnome_print_gsave(gpc);
-    gnome_print_scale(gpc, pg->width, -pg->height);
+    gnome_print_scale(gpc, pg->width, pg->height);
     gnome_print_translate(gpc, 0., -1.);
     if (gdk_pixbuf_get_n_channels(pix) == 3)
        gnome_print_rgbimage(gpc, gdk_pixbuf_get_pixels(pix),
@@ -1092,6 +1467,8 @@ void print_page(GnomePrintContext *gpc, struct Page *pg, int pageno,
   struct Item *item;
   int i;
   double *pt;
+  PangoFontDescription *font_desc;
+  PangoLayout *layout;
   
   if (pg==NULL) return;
   
@@ -1102,7 +1479,7 @@ void print_page(GnomePrintContext *gpc, struct Page *pg, int pageno,
   scale = MIN(pgwidth/pg->width, pgheight/pg->height)*0.95;
   gnome_print_translate(gpc,
      (pgwidth - scale*pg->width)/2, (pgheight + scale*pg->height)/2);
-  gnome_print_scale(gpc, scale, -scale);
+  gnome_print_scale(gpc, scale, scale);
   gnome_print_setlinejoin(gpc, 1); // round
   gnome_print_setlinecap(gpc, 1); // round
 
@@ -1117,22 +1494,36 @@ void print_page(GnomePrintContext *gpc, struct Page *pg, int pageno,
     for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next) {
       if (*abort) break;
       item = (struct Item *)itemlist->data;
-      if (item->type == ITEM_STROKE) {
+      if (item->type == ITEM_STROKE || item->type == ITEM_TEXT) {
         if ((item->brush.color_rgba & ~0xff) != (old_rgba & ~0xff))
           gnome_print_setrgbcolor(gpc, RGBA_RGB(item->brush.color_rgba));
         if ((item->brush.color_rgba & 0xff) != (old_rgba & 0xff))
           gnome_print_setopacity(gpc, RGBA_ALPHA(item->brush.color_rgba));
+        old_rgba = item->brush.color_rgba;
+      }
+      if (item->type == ITEM_STROKE) {    
         if (item->brush.thickness != old_thickness)
           gnome_print_setlinewidth(gpc, item->brush.thickness);
-        old_rgba = item->brush.color_rgba;
         old_thickness = item->brush.thickness;
         gnome_print_newpath(gpc);
         pt = item->path->coords;
-        gnome_print_moveto(gpc, pt[0], pt[1]);
+        gnome_print_moveto(gpc, pt[0], -pt[1]);
         for (i=1, pt+=2; i<item->path->num_points; i++, pt+=2)
-          gnome_print_lineto(gpc, pt[0], pt[1]);
+          gnome_print_lineto(gpc, pt[0], -pt[1]);
         gnome_print_stroke(gpc);
       }
+      if (item->type == ITEM_TEXT) {
+        layout = gnome_print_pango_create_layout(gpc);
+        font_desc = pango_font_description_from_string(item->font_name);
+        pango_font_description_set_absolute_size(font_desc,
+          item->font_size*PANGO_SCALE);
+        pango_layout_set_font_description(layout, font_desc);
+        pango_font_description_free(font_desc);
+        pango_layout_set_text(layout, item->text, -1);
+        gnome_print_moveto(gpc, item->bbox.left, -item->bbox.top);
+        gnome_print_pango_layout(gpc, layout);
+        g_object_unref(layout);
+      }
     }
   }
   
index 1ad42d4b3ccd2b7e62aa1ace010c667eb8e5a371..bdfeee7e8d51e46aefcc78ddf7fd1d2f2940a713 100644 (file)
@@ -26,6 +26,25 @@ typedef struct PdfObj {
   char **names;
 } PdfObj;
 
+typedef struct PdfFont {
+  int n_obj;
+  gboolean used_in_this_page;
+  unsigned char *filename;
+  int font_id;
+  gboolean is_truetype;
+  int glyph_page;
+  int glyphmap[256];
+  int advance[256];
+  char *glyphpsnames[256];
+  int num_glyphs_used;
+  // fields from the FT_Face
+  gdouble ft2ps;
+  int nglyphs;
+  int ascender, descender, xmin, xmax, ymin, ymax; // in PDF font units
+  gchar *fontname;
+  int flags;
+} PdfFont;
+
 #define PDFTYPE_CST 0    // intval: true=1, false=0, null=-1
 #define PDFTYPE_INT 1    // intval
 #define PDFTYPE_REAL 2   // realval
index 6e75f2b9fae06b240163570a3fa531ae92aaa18c..38bb95be8bdb4de3570c35e1987a5679c1b367e7 100644 (file)
@@ -1,6 +1,11 @@
 #include <gtk/gtk.h>
 #include <libgnomecanvas/libgnomecanvas.h>
 
+#define ENABLE_XINPUT_BUGFIX
+/* comment out this line if you are experiencing calibration problems with
+   XInput and want to try things differently. This will probably break
+   on-the-fly display rotation after application startup, though. */
+
 // PREF FILES INFO
 
 #define CONFIG_DIR ".xournal"
@@ -109,8 +114,6 @@ extern guint predef_bgcolors_rgba[COLOR_MAX];
 #define TOOLOPT_ERASER_WHITEOUT     1
 #define TOOLOPT_ERASER_STROKES      2
 
-#define HILITER_ALPHA_MASK 0xffffff80
-
 extern double predef_thickness[NUM_STROKE_TOOLS][THICKNESS_MAX];
 
 typedef struct BBox {
@@ -122,10 +125,16 @@ struct UndoErasureData;
 typedef struct Item {
   int type;
   struct Brush brush; // the brush to use, if ITEM_STROKE
+  // 'brush" also contains color info for text items
   GnomeCanvasPoints *path;
   GnomeCanvasItem *canvas_item; // the corresponding canvas item, or NULL
   struct BBox bbox;
   struct UndoErasureData *erasure; // for temporary use during erasures
+  // the following fields for ITEM_TEXT:
+  gchar *text;
+  gchar *font_name;
+  gdouble font_size;
+  GtkWidget *widget; // the widget while text is being edited (ITEM_TEMP_TEXT)
 } Item;
 
 // item type values for Item.type, UndoItem.type, ui.cur_item_type ...
@@ -148,6 +157,10 @@ typedef struct Item {
 #define ITEM_REPAINTSEL 15
 #define ITEM_MOVESEL_VERT 16
 #define ITEM_HAND 17
+#define ITEM_TEXT 18
+#define ITEM_TEMP_TEXT 19
+#define ITEM_TEXT_EDIT 20
+#define ITEM_TEXT_ATTRIB 21
 
 typedef struct Layer {
   GList *items; // the items on the layer, from bottom to top
@@ -209,6 +222,8 @@ typedef struct UIData {
   gboolean is_corestroke; // this stroke is painted with core pointer
   int screen_width, screen_height; // initial screen size, for XInput events
   double hand_refpt[2];
+  int hand_scrollto_cx, hand_scrollto_cy;
+  gboolean hand_scrollto_pending;
   char *filename;
   gchar *default_path; // default path for new notes
   gboolean view_continuous, fullscreen, maximize_at_start;
@@ -233,6 +248,11 @@ typedef struct UIData {
   GKeyFile *config_data;
 #endif
   int vertical_order[2][VBOX_MAIN_NITEMS]; // the order of interface components
+  gchar *default_font_name, *font_name;
+  gdouble default_font_size, font_size;
+  gulong resize_signal_handler;
+  gdouble hiliter_opacity;
+  guint hiliter_alpha_mask;
 } UIData;
 
 #define BRUSH_LINKED 0
@@ -248,8 +268,8 @@ typedef struct UndoErasureData {
 
 typedef struct UndoItem {
   int type;
-  struct Item *item; // for ITEM_STROKE
-  struct Layer *layer; // for ITEM_STROKE, ITEM_ERASURE, ITEM_PASTE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_MOVESEL
+  struct Item *item; // for ITEM_STROKE, ITEM_TEXT, ITEM_TEXT_EDIT, ITEM_TEXT_ATTRIB
+  struct Layer *layer; // for ITEM_STROKE, ITEM_ERASURE, ITEM_PASTE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_MOVESEL, ITEM_TEXT, ITEM_TEXT_EDIT
   struct Layer *layer2; // for ITEM_DELETE_LAYER with val=-1, ITEM_MOVESEL
   struct Page *page;  // for ITEM_NEW_BG_ONE/RESIZE, ITEM_NEW_PAGE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_DELETE_PAGE
   GList *erasurelist; // for ITEM_ERASURE
@@ -257,7 +277,9 @@ typedef struct UndoItem {
   GList *auxlist;   // for ITEM_REPAINTSEL (brushes), ITEM_MOVESEL (depths)
   struct Background *bg;  // for ITEM_NEW_BG_ONE/RESIZE, ITEM_NEW_DEFAULT_BG
   int val; // for ITEM_NEW_PAGE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_DELETE_PAGE
-  double val_x, val_y; // for ITEM_MOVESEL, ITEM_NEW_BG_RESIZE, ITEM_PAPER_RESIZE, ITEM_NEW_DEFAULT_BG
+  double val_x, val_y; // for ITEM_MOVESEL, ITEM_NEW_BG_RESIZE, ITEM_PAPER_RESIZE, ITEM_NEW_DEFAULT_BG, ITEM_TEXT_ATTRIB
+  gchar *str; // for ITEM_TEXT_EDIT, ITEM_TEXT_ATTRIB
+  struct Brush *brush; // for ITEM_TEXT_ATTRIB
   struct UndoItem *next;
   int multiop;
 } UndoItem;
index 1752fffed024ac01dfa00ee91fb7634ddcf1c2f5..471cd10902aeff61c90865a532828994816ebf62 100644 (file)
@@ -17,6 +17,7 @@
   <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
   <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
   <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
   <signal name="delete_event" handler="on_winMain_delete_event" last_modification_time="Mon, 05 Dec 2005 03:21:33 GMT"/>
 
   <child>
@@ -28,6 +29,8 @@
       <child>
        <widget class="GtkMenuBar" id="menubar">
          <property name="visible">True</property>
+         <property name="pack_direction">GTK_PACK_DIRECTION_LTR</property>
+         <property name="child_pack_direction">GTK_PACK_DIRECTION_LTR</property>
 
          <child>
            <widget class="GtkMenuItem" id="menuFile">
@@ -50,7 +53,7 @@
                  <child>
                    <widget class="GtkImageMenuItem" id="fileNewBackground">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Annotate PDF</property>
+                     <property name="label" translatable="yes">Annotate PD_F</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_fileNewBackground_activate" last_modification_time="Wed, 30 Nov 2005 18:39:59 GMT"/>
 
                  <child>
                    <widget class="GtkMenuItem" id="fileRecentFiles">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Recent Files</property>
+                     <property name="label" translatable="yes">Recent Doc_uments</property>
                      <property name="use_underline">True</property>
 
                      <child>
                      <property name="label">gtk-print</property>
                      <property name="use_stock">True</property>
                      <signal name="activate" handler="on_filePrint_activate" last_modification_time="Wed, 30 Nov 2005 18:44:18 GMT"/>
+                     <accelerator key="P" modifiers="GDK_CONTROL_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                  <child>
                    <widget class="GtkMenuItem" id="filePrintPDF">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Export to PDF</property>
+                     <property name="label" translatable="yes">_Export to PDF</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_filePrintPDF_activate" last_modification_time="Wed, 30 Nov 2005 18:44:18 GMT"/>
+                     <accelerator key="E" modifiers="GDK_CONTROL_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                      <property name="label">gtk-undo</property>
                      <property name="use_stock">True</property>
                      <signal name="activate" handler="on_editUndo_activate" last_modification_time="Wed, 30 Nov 2005 18:45:33 GMT"/>
+                     <accelerator key="Z" modifiers="GDK_CONTROL_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                      <property name="label">gtk-redo</property>
                      <property name="use_stock">True</property>
                      <signal name="activate" handler="on_editRedo_activate" last_modification_time="Wed, 30 Nov 2005 18:45:33 GMT"/>
+                     <accelerator key="Y" modifiers="GDK_CONTROL_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                      <property name="label">gtk-delete</property>
                      <property name="use_stock">True</property>
                      <signal name="activate" handler="on_editDelete_activate" last_modification_time="Wed, 30 Nov 2005 18:40:00 GMT"/>
+                     <accelerator key="Delete" modifiers="0" signal="activate"/>
                    </widget>
                  </child>
                </widget>
                  <child>
                    <widget class="GtkRadioMenuItem" id="viewContinuous">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Continuous</property>
+                     <property name="label" translatable="yes">_Continuous</property>
                      <property name="use_underline">True</property>
                      <property name="active">True</property>
                      <signal name="toggled" handler="on_viewContinuous_activate" last_modification_time="Wed, 30 Nov 2005 19:31:48 GMT"/>
                  <child>
                    <widget class="GtkRadioMenuItem" id="viewOnePage">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">One Page</property>
+                     <property name="label" translatable="yes">_One Page</property>
                      <property name="use_underline">True</property>
                      <property name="active">True</property>
                      <property name="group">viewContinuous</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <signal name="activate" handler="on_viewFullscreen_activate" last_modification_time="Thu, 19 Jan 2006 19:58:13 GMT"/>
+                     <accelerator key="F11" modifiers="0" signal="activate"/>
                    </widget>
                  </child>
 
                              <property name="label">gtk-zoom-in</property>
                              <property name="use_stock">True</property>
                              <signal name="activate" handler="on_viewZoomIn_activate" last_modification_time="Wed, 30 Nov 2005 19:31:48 GMT"/>
+                             <accelerator key="plus" modifiers="GDK_CONTROL_MASK" signal="activate"/>
                            </widget>
                          </child>
 
                              <property name="label">gtk-zoom-out</property>
                              <property name="use_stock">True</property>
                              <signal name="activate" handler="on_viewZoomOut_activate" last_modification_time="Wed, 30 Nov 2005 19:31:48 GMT"/>
+                             <accelerator key="minus" modifiers="GDK_CONTROL_MASK" signal="activate"/>
                            </widget>
                          </child>
 
                              <property name="label">gtk-zoom-100</property>
                              <property name="use_stock">True</property>
                              <signal name="activate" handler="on_viewNormalSize_activate" last_modification_time="Wed, 30 Nov 2005 19:31:48 GMT"/>
+                             <accelerator key="0" modifiers="GDK_CONTROL_MASK" signal="activate"/>
                            </widget>
                          </child>
 
                          <child>
                            <widget class="GtkImageMenuItem" id="viewPageWidth">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Page Width</property>
+                             <property name="label" translatable="yes">Page _Width</property>
                              <property name="use_underline">True</property>
                              <signal name="activate" handler="on_viewPageWidth_activate" last_modification_time="Wed, 30 Nov 2005 19:31:48 GMT"/>
+                             <accelerator key="equal" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
                              <child internal-child="image">
                                <widget class="GtkImage" id="image625">
                          <child>
                            <widget class="GtkMenuItem" id="viewSetZoom">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Set Zoom</property>
+                             <property name="label" translatable="yes">_Set Zoom</property>
                              <property name="use_underline">True</property>
                              <signal name="activate" handler="on_viewSetZoom_activate" last_modification_time="Sat, 22 Jul 2006 21:30:29 GMT"/>
                            </widget>
                  <child>
                    <widget class="GtkImageMenuItem" id="viewFirstPage">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">First Page</property>
+                     <property name="label" translatable="yes">_First Page</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_viewFirstPage_activate" last_modification_time="Wed, 30 Nov 2005 19:33:03 GMT"/>
+                     <accelerator key="Home" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
                      <child internal-child="image">
                        <widget class="GtkImage" id="image626">
                  <child>
                    <widget class="GtkImageMenuItem" id="viewPreviousPage">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Previous Page</property>
+                     <property name="label" translatable="yes">_Previous Page</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_viewPreviousPage_activate" last_modification_time="Wed, 30 Nov 2005 19:35:41 GMT"/>
+                     <accelerator key="Left" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
                      <child internal-child="image">
                        <widget class="GtkImage" id="image627">
                  <child>
                    <widget class="GtkImageMenuItem" id="viewNextPage">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Next Page</property>
+                     <property name="label" translatable="yes">_Next Page</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_viewNextPage_activate" last_modification_time="Wed, 30 Nov 2005 19:35:41 GMT"/>
+                     <accelerator key="Right" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
                      <child internal-child="image">
                        <widget class="GtkImage" id="image628">
                  <child>
                    <widget class="GtkImageMenuItem" id="viewLastPage">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Last Page</property>
+                     <property name="label" translatable="yes">_Last Page</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_viewLastPage_activate" last_modification_time="Wed, 30 Nov 2005 19:35:41 GMT"/>
+                     <accelerator key="End" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
                      <child internal-child="image">
                        <widget class="GtkImage" id="image629">
                  <child>
                    <widget class="GtkImageMenuItem" id="viewShowLayer">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Show Layer</property>
+                     <property name="label" translatable="yes">_Show Layer</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_viewShowLayer_activate" last_modification_time="Wed, 30 Nov 2005 19:40:23 GMT"/>
 
                  <child>
                    <widget class="GtkImageMenuItem" id="viewHideLayer">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Hide Layer</property>
+                     <property name="label" translatable="yes">_Hide Layer</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_viewHideLayer_activate" last_modification_time="Wed, 30 Nov 2005 19:40:23 GMT"/>
 
                  <child>
                    <widget class="GtkMenuItem" id="journalNewPageBefore">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">New Page Before</property>
+                     <property name="label" translatable="yes">New Page _Before</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalNewPageBefore_activate" last_modification_time="Wed, 30 Nov 2005 19:50:07 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalNewPageAfter">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">New Page After</property>
+                     <property name="label" translatable="yes">New Page _After</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalNewPageAfter_activate" last_modification_time="Wed, 30 Nov 2005 19:50:07 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalNewPageEnd">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">New Page At End</property>
+                     <property name="label" translatable="yes">New Page At _End</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalNewPageEnd_activate" last_modification_time="Wed, 30 Nov 2005 19:50:07 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalDeletePage">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Delete Page</property>
+                     <property name="label" translatable="yes">_Delete Page</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalDeletePage_activate" last_modification_time="Wed, 30 Nov 2005 19:50:07 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalNewLayer">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">New Layer</property>
+                     <property name="label" translatable="yes">_New Layer</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalNewLayer_activate" last_modification_time="Wed, 30 Nov 2005 19:50:07 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalDeleteLayer">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Delete Layer</property>
+                     <property name="label" translatable="yes">Delete La_yer</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalDeleteLayer_activate" last_modification_time="Wed, 30 Nov 2005 19:58:26 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalFlatten">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Flatten</property>
+                     <property name="label" translatable="yes">_Flatten</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalFlatten_activate" last_modification_time="Thu, 01 Dec 2005 21:19:12 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalPaperSize">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Paper Size</property>
+                     <property name="label" translatable="yes">Paper Si_ze</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalPaperSize_activate" last_modification_time="Wed, 30 Nov 2005 19:58:26 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalPaperColor">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Paper Color</property>
+                     <property name="label" translatable="yes">Paper _Color</property>
                      <property name="use_underline">True</property>
 
                      <child>
                          <child>
                            <widget class="GtkRadioMenuItem" id="papercolorWhite">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">white paper</property>
+                             <property name="label" translatable="yes">_white paper</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="toggled" handler="on_papercolorWhite_activate" last_modification_time="Wed, 30 Nov 2005 19:58:26 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="papercolorYellow">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">yellow paper</property>
+                             <property name="label" translatable="yes">_yellow paper</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">papercolorWhite</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="papercolorPink">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">pink paper</property>
+                             <property name="label" translatable="yes">_pink paper</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">papercolorWhite</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="papercolorOrange">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">orange paper</property>
+                             <property name="label" translatable="yes">_orange paper</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">papercolorWhite</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="papercolorBlue">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">blue paper</property>
+                             <property name="label" translatable="yes">_blue paper</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">papercolorWhite</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="papercolorGreen">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">green paper</property>
+                             <property name="label" translatable="yes">_green paper</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">papercolorWhite</property>
                  <child>
                    <widget class="GtkMenuItem" id="journalPaperStyle">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Paper Style</property>
+                     <property name="label" translatable="yes">Paper _Style</property>
                      <property name="use_underline">True</property>
 
                      <child>
                          <child>
                            <widget class="GtkRadioMenuItem" id="paperstylePlain">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">plain</property>
+                             <property name="label" translatable="yes">_plain</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="toggled" handler="on_paperstylePlain_activate" last_modification_time="Wed, 30 Nov 2005 20:06:31 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="paperstyleLined">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">lined</property>
+                             <property name="label" translatable="yes">_lined</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">paperstylePlain</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="paperstyleRuled">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">ruled</property>
+                             <property name="label" translatable="yes">_ruled</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">paperstylePlain</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="paperstyleGraph">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">graph</property>
+                             <property name="label" translatable="yes">_graph</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">paperstylePlain</property>
                  <child>
                    <widget class="GtkCheckMenuItem" id="journalApplyAllPages">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Apply To All Pages</property>
+                     <property name="label" translatable="yes">Apply _To All Pages</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <signal name="activate" handler="on_journalApplyAllPages_activate" last_modification_time="Wed, 30 Nov 2005 19:58:26 GMT"/>
                  <child>
                    <widget class="GtkImageMenuItem" id="journalLoadBackground">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Load Background</property>
+                     <property name="label" translatable="yes">_Load Background</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalLoadBackground_activate" last_modification_time="Wed, 30 Nov 2005 20:06:31 GMT"/>
 
                  <child>
                    <widget class="GtkMenuItem" id="journalScreenshot">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Background Screenshot</property>
+                     <property name="label" translatable="yes">Background Screens_hot</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalScreenshot_activate" last_modification_time="Wed, 30 Nov 2005 20:06:31 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalDefaultBackground">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Default Paper</property>
+                     <property name="label" translatable="yes">Default _Paper</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalDefaultBackground_activate" last_modification_time="Tue, 13 Dec 2005 22:35:03 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="journalSetAsDefault">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Set As Default</property>
+                     <property name="label" translatable="yes">Set As De_fault</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_journalSetAsDefault_activate" last_modification_time="Tue, 13 Dec 2005 22:35:03 GMT"/>
                    </widget>
                      <property name="use_underline">True</property>
                      <property name="active">True</property>
                      <signal name="toggled" handler="on_toolsPen_activate" last_modification_time="Thu, 01 Dec 2005 05:36:05 GMT"/>
+                     <accelerator key="P" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                      <property name="active">True</property>
                      <property name="group">toolsPen</property>
                      <signal name="toggled" handler="on_toolsEraser_activate" last_modification_time="Thu, 01 Dec 2005 05:36:05 GMT"/>
+                     <accelerator key="E" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                      <property name="active">True</property>
                      <property name="group">toolsPen</property>
                      <signal name="toggled" handler="on_toolsHighlighter_activate" last_modification_time="Thu, 01 Dec 2005 05:36:05 GMT"/>
+                     <accelerator key="H" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                      <property name="active">True</property>
                      <property name="group">toolsPen</property>
                      <signal name="toggled" handler="on_toolsText_activate" last_modification_time="Thu, 01 Dec 2005 20:54:08 GMT"/>
+                     <accelerator key="T" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                  <child>
                    <widget class="GtkRadioMenuItem" id="toolsSelectRegion">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">_Select Region</property>
+                     <property name="label" translatable="yes">Select Re_gion</property>
                      <property name="use_underline">True</property>
                      <property name="active">True</property>
                      <property name="group">toolsPen</property>
                      <signal name="toggled" handler="on_toolsSelectRegion_activate" last_modification_time="Thu, 01 Dec 2005 20:54:08 GMT"/>
+                     <accelerator key="G" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                  <child>
                    <widget class="GtkRadioMenuItem" id="toolsSelectRectangle">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Select Rectangle</property>
+                     <property name="label" translatable="yes">Select _Rectangle</property>
                      <property name="use_underline">True</property>
                      <property name="active">True</property>
                      <property name="group">toolsPen</property>
                      <signal name="toggled" handler="on_toolsSelectRectangle_activate" last_modification_time="Thu, 01 Dec 2005 20:54:08 GMT"/>
+                     <accelerator key="R" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                  <child>
                    <widget class="GtkRadioMenuItem" id="toolsVerticalSpace">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Vertical Space</property>
+                     <property name="label" translatable="yes">_Vertical Space</property>
                      <property name="use_underline">True</property>
                      <property name="active">True</property>
                      <property name="group">toolsPen</property>
                      <signal name="toggled" handler="on_toolsVerticalSpace_activate" last_modification_time="Thu, 01 Dec 2005 20:54:08 GMT"/>
+                     <accelerator key="V" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                  <child>
                    <widget class="GtkRadioMenuItem" id="toolsHand">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Hand Tool</property>
+                     <property name="label" translatable="yes">H_and Tool</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <property name="group">toolsPen</property>
                      <signal name="activate" handler="on_toolsHand_activate" last_modification_time="Wed, 20 Sep 2006 02:20:48 GMT"/>
+                     <accelerator key="A" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
                    </widget>
                  </child>
 
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorBlack">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">black</property>
+                             <property name="label" translatable="yes">blac_k</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="toggled" handler="on_colorBlack_activate" last_modification_time="Thu, 01 Dec 2005 21:56:57 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorBlue">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">blue</property>
+                             <property name="label" translatable="yes">_blue</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorRed">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">red</property>
+                             <property name="label" translatable="yes">_red</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorGreen">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">green</property>
+                             <property name="label" translatable="yes">_green</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorGray">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">gray</property>
+                             <property name="label" translatable="yes">gr_ay</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorLightBlue">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">light blue</property>
+                             <property name="label" translatable="yes">light bl_ue</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorLightGreen">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">light green</property>
+                             <property name="label" translatable="yes">light gr_een</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorMagenta">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">magenta</property>
+                             <property name="label" translatable="yes">_magenta</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorOrange">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">orange</property>
+                             <property name="label" translatable="yes">_orange</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorYellow">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">yellow</property>
+                             <property name="label" translatable="yes">_yellow</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="colorWhite">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">white</property>
+                             <property name="label" translatable="yes">_white</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">colorBlack</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="penthicknessVeryFine">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">very fine</property>
+                             <property name="label" translatable="yes">_very fine</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="toggled" handler="on_penthicknessVeryFine_activate" last_modification_time="Thu, 01 Dec 2005 19:29:18 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="penthicknessFine">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">fine</property>
+                             <property name="label" translatable="yes">_fine</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">penthicknessVeryFine</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="penthicknessMedium">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">medium</property>
+                             <property name="label" translatable="yes">_medium</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">penthicknessVeryFine</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="penthicknessThick">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">thick</property>
+                             <property name="label" translatable="yes">_thick</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">penthicknessVeryFine</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="penthicknessVeryThick">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">very thick</property>
+                             <property name="label" translatable="yes">ver_y thick</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">penthicknessVeryFine</property>
                  <child>
                    <widget class="GtkMenuItem" id="toolsEraserOptions">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Eraser Options</property>
+                     <property name="label" translatable="yes">Eraser Optio_ns</property>
                      <property name="use_underline">True</property>
 
                      <child>
                          <child>
                            <widget class="GtkRadioMenuItem" id="eraserFine">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">fine</property>
+                             <property name="label" translatable="yes">_fine</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="toggled" handler="on_eraserFine_activate" last_modification_time="Thu, 01 Dec 2005 19:29:18 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="eraserMedium">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">medium</property>
+                             <property name="label" translatable="yes">_medium</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">eraserFine</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="eraserThick">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">thick</property>
+                             <property name="label" translatable="yes">_thick</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">eraserFine</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="eraserStandard">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">standard</property>
+                             <property name="label" translatable="yes">_standard</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="toggled" handler="on_eraserStandard_activate" last_modification_time="Thu, 01 Dec 2005 19:29:18 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="eraserWhiteout">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">whiteout</property>
+                             <property name="label" translatable="yes">_whiteout</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">eraserStandard</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="eraserDeleteStrokes">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">delete strokes</property>
+                             <property name="label" translatable="yes">_delete strokes</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">eraserStandard</property>
                  <child>
                    <widget class="GtkMenuItem" id="toolsHighlighterOptions">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Highlighter Options</property>
+                     <property name="label" translatable="yes">Highlighter Opt_ions</property>
                      <property name="use_underline">True</property>
 
                      <child>
                          <child>
                            <widget class="GtkRadioMenuItem" id="highlighterFine">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">fine</property>
+                             <property name="label" translatable="yes">_fine</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="toggled" handler="on_highlighterFine_activate" last_modification_time="Thu, 01 Dec 2005 05:36:05 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="highlighterMedium">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">medium</property>
+                             <property name="label" translatable="yes">_medium</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">highlighterFine</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="highlighterThick">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">thick</property>
+                             <property name="label" translatable="yes">_thick</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">highlighterFine</property>
                  <child>
                    <widget class="GtkImageMenuItem" id="toolsTextFont">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Text Font</property>
+                     <property name="label" translatable="yes">Text _Font...</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_toolsTextFont_activate" last_modification_time="Thu, 01 Dec 2005 20:54:08 GMT"/>
+                     <accelerator key="F" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
 
                      <child internal-child="image">
                        <widget class="GtkImage" id="image634">
                  <child>
                    <widget class="GtkMenuItem" id="toolsDefaultPen">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Default Pen</property>
+                     <property name="label" translatable="yes">_Default Pen</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_toolsDefaultPen_activate" last_modification_time="Thu, 01 Dec 2005 05:36:05 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="toolsDefaultText">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Default Text</property>
+                     <property name="label" translatable="yes">Default Te_xt</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_toolsDefaultText_activate" last_modification_time="Thu, 01 Dec 2005 20:54:08 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkMenuItem" id="toolsSetAsDefault">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Set As Default</property>
+                     <property name="label" translatable="yes">_Set As Default</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_toolsSetAsDefault_activate" last_modification_time="Thu, 01 Dec 2005 05:36:05 GMT"/>
                    </widget>
                  <child>
                    <widget class="GtkCheckMenuItem" id="toolsRuler">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Ruler</property>
+                     <property name="label" translatable="yes">Ru_ler</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <signal name="toggled" handler="on_toolsRuler_activate" last_modification_time="Thu, 01 Dec 2005 20:54:08 GMT"/>
+                     <accelerator key="L" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
                    </widget>
                  </child>
                </widget>
                  <child>
                    <widget class="GtkCheckMenuItem" id="optionsUseXInput">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Use XInput</property>
+                     <property name="label" translatable="yes">Use _XInput</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <signal name="toggled" handler="on_optionsUseXInput_activate" last_modification_time="Wed, 07 Dec 2005 22:54:39 GMT"/>
                  <child>
                    <widget class="GtkCheckMenuItem" id="optionsDiscardCoreEvents">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Discard Core Events</property>
+                     <property name="label" translatable="yes">Discard _Core Events</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <signal name="toggled" handler="on_optionsDiscardCore_activate" last_modification_time="Wed, 07 Dec 2005 22:54:39 GMT"/>
                  <child>
                    <widget class="GtkCheckMenuItem" id="optionsButtonMappings">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Eraser Tip</property>
+                     <property name="label" translatable="yes">_Eraser Tip</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <signal name="activate" handler="on_optionsButtonMappings_activate" last_modification_time="Thu, 26 Jan 2006 03:45:32 GMT"/>
                  <child>
                    <widget class="GtkMenuItem" id="button2_mapping">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Button 2 Mapping</property>
+                     <property name="label" translatable="yes">Button _2 Mapping</property>
                      <property name="use_underline">True</property>
 
                      <child>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2Pen">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Pen</property>
+                             <property name="label" translatable="yes">_Pen</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="activate" handler="on_button2Pen_activate" last_modification_time="Sun, 04 Jun 2006 14:18:50 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2Eraser">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Eraser</property>
+                             <property name="label" translatable="yes">_Eraser</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button2Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2Highlighter">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Highlighter</property>
+                             <property name="label" translatable="yes">_Highlighter</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button2Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2Text">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Text</property>
+                             <property name="label" translatable="yes">_Text</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button2Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2SelectRegion">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Select Region</property>
+                             <property name="label" translatable="yes">Select Re_gion</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button2Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2SelectRectangle">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Select Rectangle</property>
+                             <property name="label" translatable="yes">Select _Rectangle</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button2Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2VerticalSpace">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Vertical Space</property>
+                             <property name="label" translatable="yes">_Vertical Space</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button2Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2Hand">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Hand Tool</property>
+                             <property name="label" translatable="yes">H_and Tool</property>
                              <property name="use_underline">True</property>
                              <property name="active">False</property>
                              <property name="group">button2Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2LinkBrush">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Link to Primary Brush</property>
+                             <property name="label" translatable="yes">_Link to Primary Brush</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="activate" handler="on_button2LinkBrush_activate" last_modification_time="Sun, 04 Jun 2006 14:33:10 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button2CopyBrush">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Copy of Current Brush</property>
+                             <property name="label" translatable="yes">_Copy of Current Brush</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button2LinkBrush</property>
                  <child>
                    <widget class="GtkMenuItem" id="button3_mapping">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Button 3 Mapping</property>
+                     <property name="label" translatable="yes">Button _3 Mapping</property>
                      <property name="use_underline">True</property>
 
                      <child>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3Pen">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Pen</property>
+                             <property name="label" translatable="yes">_Pen</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="activate" handler="on_button3Pen_activate" last_modification_time="Sun, 04 Jun 2006 14:18:50 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3Eraser">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Eraser</property>
+                             <property name="label" translatable="yes">_Eraser</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button3Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3Highlighter">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Highlighter</property>
+                             <property name="label" translatable="yes">_Highlighter</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button3Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3Text">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Text</property>
+                             <property name="label" translatable="yes">_Text</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button3Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3SelectRegion">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Select Region</property>
+                             <property name="label" translatable="yes">Select Re_gion</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button3Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3SelectRectangle">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Select Rectangle</property>
+                             <property name="label" translatable="yes">Select _Rectangle</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button3Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3VerticalSpace">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Vertical Space</property>
+                             <property name="label" translatable="yes">_Vertical Space</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button3Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3Hand">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Hand Tool</property>
+                             <property name="label" translatable="yes">H_and Tool</property>
                              <property name="use_underline">True</property>
                              <property name="active">False</property>
                              <property name="group">button3Pen</property>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3LinkBrush">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Link to Primary Brush</property>
+                             <property name="label" translatable="yes">_Link to Primary Brush</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <signal name="activate" handler="on_button3LinkBrush_activate" last_modification_time="Sun, 04 Jun 2006 14:33:10 GMT"/>
                          <child>
                            <widget class="GtkRadioMenuItem" id="button3CopyBrush">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Copy of Current Brush</property>
+                             <property name="label" translatable="yes">_Copy of Current Brush</property>
                              <property name="use_underline">True</property>
                              <property name="active">True</property>
                              <property name="group">button3LinkBrush</property>
                  <child>
                    <widget class="GtkCheckMenuItem" id="optionsAntialiasBG">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Antialiased Bitmaps</property>
+                     <property name="label" translatable="yes">_Antialiased Bitmaps</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <signal name="activate" handler="on_optionsAntialiasBG_activate" last_modification_time="Thu, 26 Jan 2006 03:42:27 GMT"/>
                  <child>
                    <widget class="GtkCheckMenuItem" id="optionsProgressiveBG">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Progressive Backgrounds</property>
+                     <property name="label" translatable="yes">_Progressive Backgrounds</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <signal name="activate" handler="on_optionsProgressiveBG_activate" last_modification_time="Thu, 26 Jan 2006 20:15:09 GMT"/>
                  <child>
                    <widget class="GtkCheckMenuItem" id="optionsPrintRuling">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Print Paper Ruling</property>
+                     <property name="label" translatable="yes">Print Paper _Ruling</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
                      <signal name="activate" handler="on_optionsPrintRuling_activate" last_modification_time="Sat, 25 Nov 2006 03:42:27 GMT"/>
                  <child>
                    <widget class="GtkMenuItem" id="optionsSavePreferences">
                      <property name="visible">True</property>
-                     <property name="label" translatable="yes">Save Preferences</property>
+                     <property name="label" translatable="yes">_Save Preferences</property>
                      <property name="use_underline">True</property>
                      <signal name="activate" handler="on_optionsSavePreferences_activate" last_modification_time="Wed, 30 Nov 2005 20:09:25 GMT"/>
                    </widget>
              <property name="homogeneous">True</property>
            </packing>
          </child>
+
+         <child>
+           <widget class="GtkToolItem" id="toolitem21">
+             <property name="visible">True</property>
+             <property name="visible_horizontal">True</property>
+             <property name="visible_vertical">True</property>
+             <property name="is_important">False</property>
+
+             <child>
+               <widget class="GtkVSeparator" id="vseparator10">
+                 <property name="visible">True</property>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="expand">False</property>
+             <property name="homogeneous">False</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="GtkToolItem" id="toolitem20">
+             <property name="visible">True</property>
+             <property name="visible_horizontal">True</property>
+             <property name="visible_vertical">True</property>
+             <property name="is_important">False</property>
+
+             <child>
+               <widget class="GtkFontButton" id="fontButton">
+                 <property name="visible">True</property>
+                 <property name="can_focus">True</property>
+                 <property name="show_style">True</property>
+                 <property name="show_size">True</property>
+                 <property name="use_font">True</property>
+                 <property name="use_size">False</property>
+                 <property name="focus_on_click">False</property>
+                 <signal name="font_set" handler="on_fontButton_font_set" last_modification_time="Sun, 12 Aug 2007 22:11:59 GMT"/>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="expand">False</property>
+             <property name="homogeneous">False</property>
+           </packing>
+         </child>
        </widget>
        <packing>
          <property name="padding">0</property>
   </child>
 </widget>
 
-<widget class="GtkFontSelectionDialog" id="fontDialog">
-  <property name="border_width">4</property>
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Select Font</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-
-  <child internal-child="cancel_button">
-    <widget class="GtkButton" id="cancel_button1">
-      <property name="visible">True</property>
-      <property name="can_default">True</property>
-      <property name="can_focus">True</property>
-      <property name="relief">GTK_RELIEF_NORMAL</property>
-      <property name="focus_on_click">True</property>
-    </widget>
-  </child>
-
-  <child internal-child="apply_button">
-    <widget class="GtkButton" id="apply_button1">
-      <property name="visible">True</property>
-      <property name="can_default">True</property>
-      <property name="can_focus">True</property>
-      <property name="relief">GTK_RELIEF_NORMAL</property>
-      <property name="focus_on_click">True</property>
-    </widget>
-  </child>
-
-  <child internal-child="ok_button">
-    <widget class="GtkButton" id="ok_button1">
-      <property name="visible">True</property>
-      <property name="can_default">True</property>
-      <property name="can_focus">True</property>
-      <property name="relief">GTK_RELIEF_NORMAL</property>
-      <property name="focus_on_click">True</property>
-    </widget>
-  </child>
-
-  <child internal-child="font_selection">
-    <widget class="GtkFontSelection" id="font_selection1">
-      <property name="border_width">4</property>
-      <property name="visible">True</property>
-      <property name="preview_text" translatable="yes">abcdefghijk ABCDEFGHIJK</property>
-    </widget>
-    <packing>
-      <property name="padding">0</property>
-      <property name="expand">True</property>
-      <property name="fill">True</property>
-    </packing>
-  </child>
-</widget>
-
-<widget class="GtkColorSelectionDialog" id="colorChooserDialog">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Select Color</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">False</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-
-  <child internal-child="cancel_button">
-    <widget class="GtkButton" id="cancel_button2">
-      <property name="visible">True</property>
-      <property name="can_default">True</property>
-      <property name="can_focus">True</property>
-      <property name="relief">GTK_RELIEF_NORMAL</property>
-      <property name="focus_on_click">True</property>
-    </widget>
-  </child>
-
-  <child internal-child="ok_button">
-    <widget class="GtkButton" id="ok_button2">
-      <property name="visible">True</property>
-      <property name="can_default">True</property>
-      <property name="can_focus">True</property>
-      <property name="relief">GTK_RELIEF_NORMAL</property>
-      <property name="focus_on_click">True</property>
-    </widget>
-  </child>
-
-  <child internal-child="help_button">
-    <widget class="GtkButton" id="help_button1">
-      <property name="visible">True</property>
-      <property name="can_default">True</property>
-      <property name="can_focus">True</property>
-      <property name="relief">GTK_RELIEF_NORMAL</property>
-      <property name="focus_on_click">True</property>
-    </widget>
-  </child>
-
-  <child internal-child="color_selection">
-    <widget class="GtkColorSelection" id="color_selection1">
-      <property name="visible">True</property>
-      <property name="has_opacity_control">False</property>
-      <property name="has_palette">False</property>
-    </widget>
-  </child>
-</widget>
-
 <widget class="GtkDialog" id="papersizeDialog">
   <property name="visible">True</property>
   <property name="title" translatable="yes">Set Paper Size</property>
   <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
   <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
   <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
   <property name="has_separator">True</property>
 
   <child internal-child="vbox">
@@ -3428,6 +3387,7 @@ points</property>
   <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
   <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
   <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
   <property name="has_separator">True</property>
 
   <child internal-child="vbox">
@@ -3546,6 +3506,7 @@ points</property>
   <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
   <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
   <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
   <property name="has_separator">True</property>
 
   <child internal-child="vbox">