Blob Blame History Raw
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.9.1"/>
<title>cairomm: user-font.cc</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">cairomm
   &#160;<span id="projectnumber">1.0</span>
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.9.1 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;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><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">user-font.cc</div>  </div>
</div><!--header-->
<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"><div class="line"><span class="preprocessor">#include &lt;cairomm/cairomm.h&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;map&gt;</span></div>
<div class="line"></div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> HEIGHT = 200.0;</div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> WIDTH = 400.0;</div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> FONT_SIZE = 64.0;</div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> TEXT_ORIGIN_Y = (HEIGHT / 2.0) + (FONT_SIZE / 2.0);</div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> TEXT_ORIGIN_X = 50.0;  <span class="comment">// arbitrary</span></div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> GLYPH_SPACING = 0.1;</div>
<div class="line"></div>
<div class="line"><span class="keyword">struct </span>GlyphBounds</div>
<div class="line">{</div>
<div class="line">  <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> glyph;</div>
<div class="line">  <span class="keywordtype">double</span> width;</div>
<div class="line">  <span class="keywordtype">double</span> height;</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><span class="comment">// an array that stores the bounds of the glyphs that we&#39;re going to draw</span></div>
<div class="line"><span class="keyword">static</span> <span class="keyword">const</span> GlyphBounds glyphs[] =</div>
<div class="line">{</div>
<div class="line">  { <span class="charliteral">&#39;c&#39;</span>, 0.45, 0.5 },</div>
<div class="line">  { <span class="charliteral">&#39;a&#39;</span>, 0.45, 0.5 },</div>
<div class="line">  { <span class="charliteral">&#39;i&#39;</span>, 0.2, 0.75 },</div>
<div class="line">  { <span class="charliteral">&#39;r&#39;</span>, 0.4, 0.5 },</div>
<div class="line">  { <span class="charliteral">&#39;o&#39;</span>, 0.44, 0.5 },</div>
<div class="line">  { <span class="charliteral">&#39;m&#39;</span>, 0.75, 0.5 },</div>
<div class="line">  { <span class="charliteral">&#39;!&#39;</span>, 0.2, 0.75 }</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><span class="comment">// A *very* simple font that just draws a box for every glyph</span></div>
<div class="line"><span class="keyword">class </span>BoxFontFace : <span class="keyword">public</span> <a name="_a0"></a><a class="code" href="classCairo_1_1UserFontFace.html">Cairo::UserFontFace</a></div>
<div class="line">{</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">  <span class="comment">// Derived user font classes should have a factory method to create an object</span></div>
<div class="line">  <span class="comment">// and return it with a RefPtr</span></div>
<div class="line">  <span class="keyword">static</span> <a name="_a1"></a><a class="code" href="classCairo_1_1RefPtr.html">Cairo::RefPtr&lt;BoxFontFace&gt;</a> create()</div>
<div class="line">  {</div>
<div class="line">    <span class="keywordflow">return</span> <a class="code" href="classCairo_1_1RefPtr.html">Cairo::RefPtr&lt;BoxFontFace&gt;</a>(<span class="keyword">new</span> BoxFontFace());</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  Cairo::ErrorStatus</div>
<div class="line">    <a name="a2"></a><a class="code" href="classCairo_1_1UserFontFace.html#af3f1d3a53a7be1d84a20609984473e07">init</a>(<span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html">Cairo::RefPtr&lt;Cairo::ScaledFont&gt;</a>&amp; <span class="comment">/*scaled_font*/</span>,</div>
<div class="line">         <span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html">Cairo::RefPtr&lt;Cairo::Context&gt;</a>&amp; <span class="comment">/*cr*/</span>,</div>
<div class="line">         <a class="code" href="namespaceCairo.html#aa7da46c699a67bfbdd5400af7e6b7b39">Cairo::FontExtents</a> &amp;extents)<span class="keyword"> override</span></div>
<div class="line"><span class="keyword">  </span>{</div>
<div class="line">    <span class="keywordtype">double</span> <a name="a3"></a><a class="codeRef" doxygen="libstdc++.tag:http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01656.html#ga8010118c8f0472172a808754940c3b66">max</a> = 0;</div>
<div class="line">    <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0; i &lt; <span class="keyword">sizeof</span> (glyphs) / <span class="keyword">sizeof</span> (GlyphBounds); ++i) {</div>
<div class="line">      <span class="keywordflow">if</span> (glyphs[i].width &gt; max)</div>
<div class="line">        max = glyphs[i].width;</div>
<div class="line">    }</div>
<div class="line">    <span class="comment">// add some spacing between characters</span></div>
<div class="line">    max += GLYPH_SPACING;</div>
<div class="line">    extents.max_x_advance = <a class="codeRef" doxygen="libstdc++.tag:http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01656.html#ga8010118c8f0472172a808754940c3b66">max</a>;</div>
<div class="line">    <span class="keywordflow">return</span> CAIRO_STATUS_SUCCESS;</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  Cairo::ErrorStatus</div>
<div class="line">  <a name="a4"></a><a class="code" href="classCairo_1_1UserFontFace.html#a43cd65b62eab686477d3773e6fd98b46">unicode_to_glyph</a> (<span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html">Cairo::RefPtr&lt;Cairo::ScaledFont&gt;</a>&amp; <span class="comment">/*scaled_font*/</span>,</div>
<div class="line">                    <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> unicode, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>&amp; glyph)<span class="keyword"> override</span></div>
<div class="line"><span class="keyword">  </span>{</div>
<div class="line">    glyph = 0;</div>
<div class="line">    <span class="comment">// yes this is a stupid an ineffienct way to do this but we only have a few</span></div>
<div class="line">    <span class="comment">// glyphs and this is just demonstration code</span></div>
<div class="line">    <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0; i &lt; <span class="keyword">sizeof</span> (glyphs) / <span class="keyword">sizeof</span> (GlyphBounds); ++i) {</div>
<div class="line">      <span class="keywordflow">if</span> (glyphs[i].glyph == unicode) {</div>
<div class="line">        <span class="comment">// glyph 0 is often a special glyph-not-found value, so offset it by 1</span></div>
<div class="line">        glyph = i+1;</div>
<div class="line">        <span class="keywordflow">break</span>;</div>
<div class="line">      }</div>
<div class="line">    }</div>
<div class="line">    <span class="keywordflow">return</span> CAIRO_STATUS_SUCCESS;</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  Cairo::ErrorStatus</div>
<div class="line">  <a name="a5"></a><a class="code" href="classCairo_1_1UserFontFace.html#a2e53435e92f9975213bd19969cb69375">render_glyph</a>(<span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html">Cairo::RefPtr&lt;Cairo::ScaledFont&gt;</a>&amp; <span class="comment">/*scaled_font*/</span>,</div>
<div class="line">               <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> glyph,</div>
<div class="line">               <span class="keyword">const</span> <a class="code" href="classCairo_1_1RefPtr.html">Cairo::RefPtr&lt;Cairo::Context&gt;</a>&amp; cr,</div>
<div class="line">               <a class="code" href="namespaceCairo.html#af6d8a4744616383984c99f8f052c7a5d">Cairo::TextExtents</a>&amp; metrics)<span class="keyword"> override</span></div>
<div class="line"><span class="keyword">  </span>{</div>
<div class="line">    <span class="comment">// check that the glyph is in our table</span></div>
<div class="line">    <span class="keywordflow">if</span> (glyph &gt;= 1 &amp;&amp; glyph &lt;= <span class="keyword">sizeof</span>(glyphs)/<span class="keyword">sizeof</span>(GlyphBounds)) {</div>
<div class="line">      cr-&gt;<a name="a6"></a><a class="code" href="classCairo_1_1Context.html#a9ad2649d95e81a65aa0c581c4345375e">set_line_width</a>(0.05);</div>
<div class="line">      <span class="comment">// Need a negative Y value since the text origin is at the bottom left point</span></div>
<div class="line">      <span class="comment">// and cairo&#39;s positive Y axis is down and we want to draw up</span></div>
<div class="line">      cr-&gt;<a name="a7"></a><a class="code" href="classCairo_1_1Context.html#a85ee124b89c43dc29ff0d964bd005c11">rectangle</a>(0.0, 0.0, glyphs[glyph-1].width, -glyphs[glyph-1].height);</div>
<div class="line">      cr-&gt;<a name="a8"></a><a class="code" href="classCairo_1_1Context.html#a8e4acbb44f4b3fac00ee93f6251d6d17">stroke</a>();</div>
<div class="line">      metrics.x_advance = glyphs[glyph-1].width + GLYPH_SPACING;</div>
<div class="line">    }</div>
<div class="line">    <span class="keywordflow">return</span> CAIRO_STATUS_SUCCESS;</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line"><span class="keyword">protected</span>:</div>
<div class="line">  <span class="comment">// FontFace is a ref-counted object, so the constructor should be protected so</span></div>
<div class="line">  <span class="comment">// it is not created without a refptr to manage it.  See the create() method</span></div>
<div class="line">  BoxFontFace() : UserFontFace() { }</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span>, <span class="keywordtype">char</span>**)</div>
<div class="line">{</div>
<div class="line">  <span class="keyword">auto</span> surface =</div>
<div class="line">    <a name="a9"></a><a class="code" href="classCairo_1_1ImageSurface.html#a82887e1a0480ab16aa891e135f2b28d6">Cairo::ImageSurface::create</a>(<a name="a10"></a><a class="code" href="namespaceCairo.html#ad3f86970e1bd354b263303c9b8759166afc97f1888578477fd656cf72d3421fbc">Cairo::FORMAT_ARGB32</a>, WIDTH, HEIGHT);</div>
<div class="line">  <span class="keyword">auto</span> cr = <a name="a11"></a><a class="code" href="classCairo_1_1Context.html#a9a27f6ec57d788fd3ecbc310aeb24d99">Cairo::Context::create</a>(surface);</div>
<div class="line">  <span class="comment">// fill background in white</span></div>
<div class="line">  cr-&gt;<a name="a12"></a><a class="code" href="classCairo_1_1Context.html#aff3f3fc62bdf862646bb8cc568c30b2a">set_source_rgb</a>(1.0, 1.0, 1.0);</div>
<div class="line">  cr-&gt;<a name="a13"></a><a class="code" href="classCairo_1_1Context.html#ad919eae3bc3b9827a3c1ceff2d86833e">paint</a>();</div>
<div class="line"></div>
<div class="line">  <span class="comment">// draw a little dot at the point where text will be drawn</span></div>
<div class="line">  cr-&gt;<a name="a14"></a><a class="code" href="classCairo_1_1Context.html#aaa96080beea581244f0a3838fb7c9ee6">arc</a>(TEXT_ORIGIN_X, TEXT_ORIGIN_Y, FONT_SIZE / 4.0, 0, 2*M_PI);</div>
<div class="line">  cr-&gt;<a name="a15"></a><a class="code" href="classCairo_1_1Context.html#af9267aed8eb866701178dcada6c7e51a">set_source_rgba</a>(0.0, 1.0, 0.0, 0.5);</div>
<div class="line">  cr-&gt;<a name="a16"></a><a class="code" href="classCairo_1_1Context.html#a0a484790884dd138108b07c0ebbbe21d">fill</a>();</div>
<div class="line"></div>
<div class="line">  <span class="comment">// draw the text</span></div>
<div class="line">  cr-&gt;<a name="a17"></a><a class="code" href="classCairo_1_1Context.html#a4086700b5f780fd3fb94bea941895022">move_to</a>(TEXT_ORIGIN_X, TEXT_ORIGIN_Y);</div>
<div class="line">  cr-&gt;<a class="code" href="classCairo_1_1Context.html#aff3f3fc62bdf862646bb8cc568c30b2a">set_source_rgb</a>(0.8, 0.2, 0.2);</div>
<div class="line">  <span class="keyword">auto</span> font = BoxFontFace::create();</div>
<div class="line">  cr-&gt;<a name="a18"></a><a class="code" href="classCairo_1_1Context.html#a9b344db51097aba30e36452e1364faef">set_font_face</a>(font);</div>
<div class="line">  cr-&gt;<a name="a19"></a><a class="code" href="classCairo_1_1Context.html#ac8a04a09c2e871a470fd030edb45b024">set_font_size</a>(FONT_SIZE);</div>
<div class="line">  cr-&gt;<a name="a20"></a><a class="code" href="classCairo_1_1Context.html#a584596d6f12dbea30519b908cacce038">show_text</a>(<span class="stringliteral">&quot;cairomm!&quot;</span>);</div>
<div class="line"></div>
<div class="line">  <span class="comment">// Now show it with the toy text API to demonstrate how the glyphs match up</span></div>
<div class="line">  cr-&gt;<a class="code" href="classCairo_1_1Context.html#a4086700b5f780fd3fb94bea941895022">move_to</a>(TEXT_ORIGIN_X, TEXT_ORIGIN_Y);</div>
<div class="line">  cr-&gt;<a class="code" href="classCairo_1_1Context.html#af9267aed8eb866701178dcada6c7e51a">set_source_rgba</a>(0.2, 0.2, 0.2, 0.3);</div>
<div class="line">  <span class="keyword">auto</span> toy_font =</div>
<div class="line">    <a name="a21"></a><a class="code" href="classCairo_1_1ToyFontFace.html#a07c0ca7fd0dc54c31bfa1d8a813aff59">Cairo::ToyFontFace::create</a>(<span class="stringliteral">&quot;Bitstream Charter&quot;</span>,</div>
<div class="line">                               <a name="a22"></a><a class="code" href="namespaceCairo.html#a0a2c19fefac301a702a6b7fdb368bf55a428cfea8fca5951033f3d433855cb97d">Cairo::FONT_SLANT_NORMAL</a>,</div>
<div class="line">                               <a name="a23"></a><a class="code" href="namespaceCairo.html#ad8514818fb9292a5864b57f4b8a1e546a438bd2ac850ef23ce7a537ae3395f398">Cairo::FONT_WEIGHT_BOLD</a>);</div>
<div class="line">  cr-&gt;<a class="code" href="classCairo_1_1Context.html#a9b344db51097aba30e36452e1364faef">set_font_face</a>(toy_font);</div>
<div class="line">  cr-&gt;<a class="code" href="classCairo_1_1Context.html#ac8a04a09c2e871a470fd030edb45b024">set_font_size</a>(FONT_SIZE);</div>
<div class="line">  cr-&gt;<a class="code" href="classCairo_1_1Context.html#a584596d6f12dbea30519b908cacce038">show_text</a>(<span class="stringliteral">&quot;cairomm!&quot;</span>);</div>
<div class="line"></div>
<div class="line">  <span class="keyword">const</span> <span class="keywordtype">char</span>* filename = <span class="stringliteral">&quot;user-font.png&quot;</span>;</div>
<div class="line">  <span class="keywordflow">try</span> {</div>
<div class="line">    surface-&gt;write_to_png(filename);</div>
<div class="line">    <a name="a24"></a>std::cout &lt;&lt; <span class="stringliteral">&quot;Wrote Image &quot;</span> &lt;&lt; filename &lt;&lt; <a name="a25"></a><a class="codeRef" doxygen="libstdc++.tag:http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01616.html#a8b3758bb8f17c440c7963363f42f69f3">std::endl</a>;</div>
<div class="line">    <span class="keywordflow">return</span> 0;</div>
<div class="line">  } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a name="_a26"></a><a class="codeRef" doxygen="libstdc++.tag:http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00694.html">std::exception</a>&amp; e)</div>
<div class="line">  {</div>
<div class="line">    std::cout &lt;&lt; <span class="stringliteral">&quot;** Unable to write Image &quot;</span> &lt;&lt; filename &lt;&lt; <a class="codeRef" doxygen="libstdc++.tag:http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/" href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01616.html#a8b3758bb8f17c440c7963363f42f69f3">std::endl</a>;</div>
<div class="line">    <span class="keywordflow">return</span> 1;</div>
<div class="line">  }</div>
<div class="line">}</div>
</div><!-- fragment --> </div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Mon Sep 21 2015 21:56:36 for cairomm by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
</body>
</html>