<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>cairomm: user-font.cc</title> <link href="cairomm.css" rel="stylesheet" type="text/css"> </head> <body> <!-- Generated by Doxygen 1.7.3 --> <div id="navrow1" class="tabs"> <ul class="tablist"> <li><a href="index.html"><span>Main Page</span></a></li> <li><a href="pages.html"><span>Related Pages</span></a></li> <li><a href="namespaces.html"><span>Namespaces</span></a></li> <li><a href="annotated.html"><span>Classes</span></a></li> <li><a href="examples.html"><span>Examples</span></a></li> </ul> </div> </div> <div class="header"> <div class="headertitle"> <h1>user-font.cc</h1> </div> </div> <div class="contents"> <p>A relatively simple example of using <a class="el" href="classCairo_1_1UserFontFace.html" title="Font support with font data provided by the user.">Cairo::UserFontFace</a></p> <div class="fragment"><pre class="fragment"><span class="preprocessor">#include <cairomm/cairomm.h></span> <span class="preprocessor">#include <iostream></span> <span class="preprocessor">#include <map></span> <span class="keyword">const</span> <span class="keywordtype">double</span> HEIGHT = 200.0; <span class="keyword">const</span> <span class="keywordtype">double</span> WIDTH = 400.0; <span class="keyword">const</span> <span class="keywordtype">double</span> FONT_SIZE = 64.0; <span class="keyword">const</span> <span class="keywordtype">double</span> TEXT_ORIGIN_Y = (HEIGHT / 2.0) + (FONT_SIZE / 2.0); <span class="keyword">const</span> <span class="keywordtype">double</span> TEXT_ORIGIN_X = 50.0; <span class="comment">// arbitrary</span> <span class="keyword">const</span> <span class="keywordtype">double</span> GLYPH_SPACING = 0.1; <span class="keyword">struct </span>GlyphBounds { <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> glyph; <span class="keywordtype">double</span> width; <span class="keywordtype">double</span> height; }; <span class="comment">// an array that stores the bounds of the glyphs that we're going to draw</span> <span class="keyword">static</span> <span class="keyword">const</span> GlyphBounds glyphs[] = { { <span class="charliteral">'c'</span>, 0.45, 0.5 }, { <span class="charliteral">'a'</span>, 0.45, 0.5 }, { <span class="charliteral">'i'</span>, 0.2, 0.75 }, { <span class="charliteral">'r'</span>, 0.4, 0.5 }, { <span class="charliteral">'o'</span>, 0.44, 0.5 }, { <span class="charliteral">'m'</span>, 0.75, 0.5 }, { <span class="charliteral">'!'</span>, 0.2, 0.75 } }; <span class="comment">// A *very* simple font that just draws a box for every glyph</span> <span class="keyword">class </span>BoxFontFace : <span class="keyword">public</span> Cairo::UserFontFace { <span class="keyword">public</span>: <span class="comment">// Derived user font classes should have a factory method to create an object</span> <span class="comment">// and return it with a RefPtr</span> <span class="keyword">static</span> <a name="_a0"></a><a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<BoxFontFace></a> create() { <span class="keywordflow">return</span> <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<BoxFontFace></a>(<span class="keyword">new</span> BoxFontFace()); } <span class="keyword">virtual</span> Cairo::ErrorStatus init(<span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<Cairo::ScaledFont></a>& <span class="comment">/*scaled_font*/</span>, <span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<Cairo::Context></a>& <span class="comment">/*cr*/</span>, <a class="code" href="namespaceCairo.html#aa7da46c699a67bfbdd5400af7e6b7b39" title="See the cairo_font_extents_t reference in the cairo manual for more information.">Cairo::FontExtents</a> &extents) { <span class="keywordtype">double</span> <a name="a1"></a><a class="codeRef" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01176.html#ga8010118c8f0472172a808754940c3b66">max</a> = 0; <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0; i < <span class="keyword">sizeof</span> (glyphs) / <span class="keyword">sizeof</span> (GlyphBounds); ++i) { <span class="keywordflow">if</span> (glyphs[i].width > max) max = glyphs[i].width; } <span class="comment">// add some spacing between characters</span> max += GLYPH_SPACING; extents.max_x_advance = <a class="codeRef" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01176.html#ga8010118c8f0472172a808754940c3b66">max</a>; <span class="keywordflow">return</span> CAIRO_STATUS_SUCCESS; } <span class="keyword">virtual</span> Cairo::ErrorStatus unicode_to_glyph (<span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<Cairo::ScaledFont></a>& <span class="comment">/*scaled_font*/</span>, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> unicode, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>& glyph) { glyph = 0; <span class="comment">// yes this is a stupid an ineffienct way to do this but we only have a few</span> <span class="comment">// glyphs and this is just demonstration code</span> <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0; i < <span class="keyword">sizeof</span> (glyphs) / <span class="keyword">sizeof</span> (GlyphBounds); ++i) { <span class="keywordflow">if</span> (glyphs[i].glyph == unicode) { <span class="comment">// glyph 0 is often a special glyph-not-found value, so offset it by 1</span> glyph = i+1; <span class="keywordflow">break</span>; } } <span class="keywordflow">return</span> CAIRO_STATUS_SUCCESS; } <span class="keyword">virtual</span> Cairo::ErrorStatus render_glyph(<span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<Cairo::ScaledFont></a>& <span class="comment">/*scaled_font*/</span>, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> glyph, <span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<Cairo::Context></a>& cr, <a class="code" href="namespaceCairo.html#af6d8a4744616383984c99f8f052c7a5d" title="See the cairo_text_extents_t reference in the cairo manual for more information.">Cairo::TextExtents</a>& metrics) { <span class="comment">// check that the glyph is in our table</span> <span class="keywordflow">if</span> (glyph >= 1 && glyph <= <span class="keyword">sizeof</span>(glyphs)/<span class="keyword">sizeof</span>(GlyphBounds)) { cr->set_line_width(0.05); <span class="comment">// Need a negative Y value since the text origin is at the bottom left point</span> <span class="comment">// and cairo's positive Y axis is down and we want to draw up</span> cr->rectangle(0.0, 0.0, glyphs[glyph-1].width, -glyphs[glyph-1].height); cr->stroke(); metrics.x_advance = glyphs[glyph-1].width + GLYPH_SPACING; } <span class="keywordflow">return</span> CAIRO_STATUS_SUCCESS; } <span class="keyword">protected</span>: <span class="comment">// FontFace is a ref-counted object, so the constructor should be protected so</span> <span class="comment">// it is not created without a refptr to manage it. See the create() method</span> BoxFontFace() : UserFontFace() { } }; <span class="keywordtype">int</span> main(<span class="keywordtype">int</span>, <span class="keywordtype">char</span>**) { <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<Cairo::ImageSurface></a> surface = <a name="a2"></a><a class="code" href="classCairo_1_1ImageSurface.html#a82887e1a0480ab16aa891e135f2b28d6" title="Creates an image surface of the specified format and dimensions.">Cairo::ImageSurface::create</a>(<a name="a3"></a><a class="code" href="namespaceCairo.html#ad3f86970e1bd354b263303c9b8759166afc97f1888578477fd656cf72d3421fbc">Cairo::FORMAT_ARGB32</a>, WIDTH, HEIGHT); <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<Cairo::Context></a> cr = <a name="a4"></a><a class="code" href="classCairo_1_1Context.html#a9a27f6ec57d788fd3ecbc310aeb24d99">Cairo::Context::create</a>(surface); <span class="comment">// fill background in white</span> cr->set_source_rgb(1.0, 1.0, 1.0); cr->paint(); <span class="comment">// draw a little dot at the point where text will be drawn</span> cr->arc(TEXT_ORIGIN_X, TEXT_ORIGIN_Y, FONT_SIZE / 4.0, 0, 2*M_PI); cr->set_source_rgba(0.0, 1.0, 0.0, 0.5); cr->fill(); <span class="comment">// draw the text</span> cr->move_to(TEXT_ORIGIN_X, TEXT_ORIGIN_Y); cr->set_source_rgb(0.8, 0.2, 0.2); <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<BoxFontFace></a> font = BoxFontFace::create(); cr->set_font_face(font); cr->set_font_size(FONT_SIZE); cr->show_text(<span class="stringliteral">"cairomm!"</span>); <span class="comment">// Now show it with the toy text API to demonstrate how the glyphs match up</span> cr->move_to(TEXT_ORIGIN_X, TEXT_ORIGIN_Y); cr->set_source_rgba(0.2, 0.2, 0.2, 0.3); <a class="code" href="classCairo_1_1RefPtr.html" title="RefPtr&lt;&gt; is a reference-counting shared smartpointer.">Cairo::RefPtr<Cairo::ToyFontFace></a> toy_font = <a name="a5"></a><a class="code" href="classCairo_1_1ToyFontFace.html#a07c0ca7fd0dc54c31bfa1d8a813aff59" title="Creates a font face from a triplet of family, slant, and weight.">Cairo::ToyFontFace::create</a>(<span class="stringliteral">"Bitstream Charter"</span>, <a name="a6"></a><a class="code" href="namespaceCairo.html#a0a2c19fefac301a702a6b7fdb368bf55a428cfea8fca5951033f3d433855cb97d">Cairo::FONT_SLANT_NORMAL</a>, <a name="a7"></a><a class="code" href="namespaceCairo.html#ad8514818fb9292a5864b57f4b8a1e546a438bd2ac850ef23ce7a537ae3395f398">Cairo::FONT_WEIGHT_BOLD</a>); cr->set_font_face(toy_font); cr->set_font_size(FONT_SIZE); cr->show_text(<span class="stringliteral">"cairomm!"</span>); <span class="keyword">const</span> <span class="keywordtype">char</span>* filename = <span class="stringliteral">"user-font.png"</span>; <span class="keywordflow">try</span> { surface->write_to_png(filename); <a name="a8"></a><a class="codeRef" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01136.html#aaf93fdf0812752e0e02c501dea1b38f0">std::cout</a> << <span class="stringliteral">"Wrote Image "</span> << filename << <a name="a9"></a><a class="codeRef" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01136.html#a9e2ba1ed9813a1f03adc9a87dbf491a5">std::endl</a>; <span class="keywordflow">return</span> 0; } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a name="_a10"></a><a class="codeRef" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00469.html">std::exception</a>& e) { <a class="codeRef" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01136.html#aaf93fdf0812752e0e02c501dea1b38f0">std::cout</a> << <span class="stringliteral">"** Unable to write Image "</span> << filename << <a class="codeRef" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01136.html#a9e2ba1ed9813a1f03adc9a87dbf491a5">std::endl</a>; <span class="keywordflow">return</span> 1; } } </pre></div> </div> </div> <hr class="footer"/><address class="footer"><small>Generated on Mon May 9 2011 09:51:07 for cairomm by  <a href="http://www.doxygen.org/index.html"> <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.3 </small></address> </body> </html>