Sophie

Sophie

distrib > Mageia > 7 > armv7hl > media > core-release > by-pkgid > 179f6d9d76f967979ea9b6d2656e8a89 > files > 92

libquesoglc0-0.7.2-10.mga7.armv7hl.rpm

<!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>Measurement tutorial</title>
<link href="quesoglc.css" rel="stylesheet" type="text/css">
</head><body>
<table>
  <tr valign="top">
    <td width="190" align="center">
      <table class="qmenu" cellspacing="0">
        <tr>
          <td class="qglobal">
            <ul class="qmenu">
	      <li class="mainmenu"><a href="index.html" >Main</a></li>
            </ul>
          </td>
	</tr>
        <tr>
            <td class="qtitle">Tutorials</td>
        </tr>
	<tr>
	  <td class="qglobal">
            <ul class="qmenu">
	      <li class="mainmenu"><a href="tutorial.html">First Steps</a></li>
	      <li class="mainmenu"><a href="tutorial2.html">Measurement</a></li>
            </ul>
          </td>
	</tr>
        <tr>
            <td class="qtitle">Documentation</td>
        </tr>
	<tr>
	  <td class="qglobal">
            <ul class="qmenu">
	      <li class="mainmenu"><a href="overview.html">Overview</a></li>
	      <li class="mainmenu"><a href="glyph.html">Glyph conventions</a></li>
	      <li class="mainmenu"><a href="machinedef.html">Machine definition</a></li>
	      <li class="mainmenu"><a href="group__context.html">Context State</a></li>
	      <li class="mainmenu"><a href="group__font.html">Fonts</a></li>
	      <li class="mainmenu"><a href="group__global.html">Global</a></li>
	      <li class="mainmenu"><a href="group__master.html">Master</a></li>
	      <li class="mainmenu"><a href="group__transform.html">Transformation</a></li>
	      <li class="mainmenu"><a href="group__render.html">Render</a></li>
	      <li class="mainmenu"><a href="group__measure.html">Measurement</a></li>
            </ul>
          </td>
	</tr>
      </table>
    </td>
    <td>
      <table>
        <tr>
	  <td class="main">
<!-- Generated by Doxygen 1.8.14 -->
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Measurement tutorial </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="preamble"></a>
Preamble</h1>
<p>In this tutorial we will see how to use the <a class="el" href="group__measure.html">Measurement commands</a> of GLC and what they are intended for. It is assumed that you have a basic knowledge of the GLC API (the <a class="el" href="tutorial.html">First Steps</a> tutorial is a good place to start with) and that you have read the <a class="el" href="glyph.html">Glyph Conventions</a> so that you know what a <em>bounding box</em> and a <em>baseline</em> are.</p>
<p>Basically, in order to display some text an application have to go through the following stages :</p><ol type="1">
<li>The <b>text layout</b> determines where and how the text must be layed out : this task can be as simple as computing the location of the word <em>"Score"</em> so that it appears in the upper left corner of the screen or as complex as laying out a complete document with titles, fonts, styles, paragraphs and chapters; just like word processors do.</li>
<li>The <b>text rendering</b> draws the text that has been layed out in the previous stage : the application determines which glyphs of which fonts it should use in order to obtain the desired result, eventually converts data into graphic primitives, and finally sends the required commands to the output device which can be either a screen or a printer.</li>
</ol>
<p>The GLC API only covers the later stage and provides no layout services : it has no concept of sentence, line break or paragraph. GLC only manipulates <em>strings</em> that it views as a succession of characters that has to be rendered on the screen in a row. So in order to be able to handle complex text layout the client application has to decompose text in several strings that can be rendered by GLC. This can be done by <em>rendering engines</em> like <a href="http://www.pango.org">Pango</a> or <a href="http://www-306.ibm.com/software/globalization/icu/index.jsp">ICU</a>.</p>
<p>For instance, when a sentence is larger than the width of the output device, it has to be broken into two or more lines before being rendered so that it can be read. In order to determine where to put the line break(s), the layout engine needs to know the width of the output device as well as the size of the characters used to render the text (actually it also needs to understand the exact structure of the sentence to prevent the line break to take place in the middle of a word or between a word and a comma for example). This is where <a class="el" href="group__measure.html">Measurement commands</a> take place.</p>
<p><em>General layout management is far beyond the scope of this tutorial but you can find some more informations at the <a href="http://www.unicode.org">Unicode web site</a></em>.</p>
<p>Another application of the bounding boxes is the visibility test. For example, one can get the bouding box of a letter or a string, tranform it into the screen coordinates and test the result against the viewport. If the bounding box is located out of the viewport then there is no need to render the string. Such a test may help to speed up a program.</p>
<h1><a class="anchor" id="baseelements"></a>
Base elements</h1>
<p>In this tutorial we will see how to render the string <em>Hello world!</em> with a bounding box around the capital letter <em>"H"</em> and another bounding box around the 4 last letters of the word <em>"Hello"</em> as shown in the image below.</p>
<div class="image">
<img src="tutorial2.png" alt="tutorial2.png"/>
<div class="caption">
Figure 1 - The result of the tutorial</div></div>
<p>The code presented in the <a class="el" href="tutorial.html">First Steps</a> tutorial is the starting point of the current example. Notice however that it has been slightly changed : a call to the function <a class="el" href="group__transform.html#ga978d760fac5b11cd876b8c3a0055dadf" title="This command assigns the value [a b c d] to the floating point vector variable GLC_BITMAP_MATRIX, where inAngle is measured in degrees,  and   . ">glcRotate()</a> has been added in order to rotate the text of 10 degrees counterclockwise. The call to <a class="el" href="group__master.html#gab0b37f7b9f9459aef7ec645a66bac4a7" title="This command appends the string inCatalog to the list GLC_CATALOG_LIST. ">glcAppendCatalog()</a> has also been commented out : it is not needed if <a href="http://www.fontconfig.org">Fontconfig</a> has been carefully installed (which is the case on most of the recent Linux distributions).</p>
<div class="fragment"><div class="line">GLint ctx, myFont;</div><div class="line"></div><div class="line"><span class="comment">// Set up and initialize GLC</span></div><div class="line">ctx = <a class="code" href="group__global.html#ga65c4f22e1a75bca7edafe35fe6b185ee">glcGenContext</a>();</div><div class="line"><a class="code" href="group__global.html#gaaa17c69ee70f9e8a900dc9c6830f3f09">glcContext</a>(ctx);</div><div class="line"><span class="comment">//glcAppendCatalog(&quot;/usr/lib/X11/fonts/Type1&quot;);</span></div><div class="line"></div><div class="line"><span class="comment">// Create a font &quot;Palatino Bold&quot;</span></div><div class="line">myFont = <a class="code" href="group__font.html#ga658c40ba0437274cf2849bc3dac4dd20">glcGenFontID</a>();</div><div class="line"><a class="code" href="group__font.html#gacc8675929261b5f04882d375cb54a530">glcNewFontFromFamily</a>(myFont, <span class="stringliteral">&quot;Palatino&quot;</span>);</div><div class="line"><a class="code" href="group__font.html#gab9800f5153d46bd293b62dc7bfcd364f">glcFontFace</a>(myFont, <span class="stringliteral">&quot;Bold&quot;</span>);</div><div class="line"><a class="code" href="group__font.html#gaab2c8a01997c3827b10aebedd8e78501">glcFont</a>(myFont);</div><div class="line"></div><div class="line"><span class="comment">// Render the text at a size of 100 points</span></div><div class="line"><a class="code" href="group__transform.html#ga71a9a779d35bc8c4631de7cbda21cea6">glcScale</a>(100.f, 100.f);</div><div class="line"><a class="code" href="group__transform.html#ga978d760fac5b11cd876b8c3a0055dadf">glcRotate</a>(10.f); <span class="comment">// Rotate the text of 10 degrees counterclockwise</span></div><div class="line"></div><div class="line"><span class="comment">// Render &quot;Hello world!&quot;</span></div><div class="line">glColor3f(1.f, 0.f, 0.f);</div><div class="line">glRasterPos2f(50.f, 50.f);</div><div class="line"><a class="code" href="group__render.html#ga93708ef20c96fd01019fcd9eb18f0b03">glcRenderString</a>(<span class="stringliteral">&quot;Hello world!&quot;</span>);</div></div><!-- fragment --><h1><a class="anchor" id="hbbox"></a>
Drawing the bounding box of a single letter</h1>
<p>GLC defines the geometry of a bounding box by the coordinates [ x<sub>lb</sub> y<sub>lb</sub> x<sub>rb</sub> y<sub>rb</sub> x<sub>rt</sub> y<sub>rt</sub> x<sub>lt</sub> y<sub>lt</sub> ] of its corners. Each point is given in 2D coordinates : <em>z</em> is always assumed to be <em>0</em> and <em>w</em> to be <em>1</em>. They are <em>object coordinates</em> which means that they are affected by both the <b>GL_MODELVIEW</b> and the <b>GL_PROJECTION</b> transformations. Moreover if the value of the variable <b>GLC_RENDER_STYLE</b> is <b>GLC_BITMAP</b> then each point is transformed by the 2x2 <b>GLC_BITMAP_MATRIX</b>.</p>
<div class="image">
<img src="measure.png" alt="measure.png"/>
<div class="caption">
Figure 2 - Metrics coordinates</div></div>
<p>Since there are 4 corners, we need to define an array of 8 floating point numbers which will contain the <em>(x, y)</em> coordinates of the bounding box.</p>
<div class="fragment"><div class="line">GLfloat bbox[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};</div></div><!-- fragment --><p>The bounding box of the letter <em>"H"</em> is stored in the <em>bbox</em> array by calling <a class="el" href="group__measure.html#ga0662d416bafc192517b0155ebba66579" title="This command is identical to the command glcRenderChar(), except that instead of rendering the charac...">glcGetCharMetric()</a> :</p>
<div class="fragment"><div class="line"><a class="code" href="group__measure.html#ga0662d416bafc192517b0155ebba66579">glcGetCharMetric</a>(<span class="charliteral">&#39;H&#39;</span>, GLC_BOUNDS, bbox);</div></div><!-- fragment --><p>GLC assumes that the origin of the layout is <em></em>(0,0) but in our example the string <em>"Hello world!"</em> has been rendered from the coordinates <em></em>(50,50) so we need to translate the bounding box before it is rendered :</p>
<div class="fragment"><div class="line"><span class="comment">// Translate the bbox to the origin of the layout</span></div><div class="line">glTranslatef(50.f, 50.f, 0.f);</div><div class="line"><span class="comment">// Render the bounding box</span></div><div class="line">glBegin(GL_LINE_LOOP);</div><div class="line"><span class="keywordflow">for</span> (i = 0; i &lt; 4; i++)</div><div class="line">  glVertex2fv(&amp;bbox[2*i]);</div><div class="line">glEnd();</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd><em>We do not need to rotate the bounding box of 10 degrees since it has already been done by GLC. If we were using a <b>GLC_RENDER_STYLE</b> that were not <b>GLC_BITMAP</b>, we would need to add a call to <code>glRotatef(0., 0., 1., 10.);</code></em></dd></dl>
<h1><a class="anchor" id="ellobbox"></a>
Drawing the bounding box of a string</h1>
<p>We now want to draw the bounding box of the 4 last letters of the word <em>Hello</em>. Although this can be achieved by computing the bounding box of the bounding boxes of each character, this would be rather tedious, so GLC provides a function that does the work for us : <a class="el" href="group__measure.html#ga8c17cf3164f9b45d293704dd511b5e94" title="This command measures the layout that would result from rendering a string and stores the measurement...">glcMeasureString()</a>.</p>
<p>Actually, <a class="el" href="group__measure.html#ga8c17cf3164f9b45d293704dd511b5e94" title="This command measures the layout that would result from rendering a string and stores the measurement...">glcMeasureString()</a> is designed to measure the whole string metrics and can also store on demand the metrics of each character of the string. Here we only want the <em>"ello"</em> string metrics so we set the first parameter of <a class="el" href="group__measure.html#ga8c17cf3164f9b45d293704dd511b5e94" title="This command measures the layout that would result from rendering a string and stores the measurement...">glcMeasureString()</a> to <b>GL_FALSE</b> :</p>
<div class="fragment"><div class="line"><a class="code" href="group__measure.html#ga8c17cf3164f9b45d293704dd511b5e94">glcMeasureString</a>(GL_FALSE, <span class="stringliteral">&quot;ello&quot;</span>);</div></div><!-- fragment --><p>At this stage, the metrics are computed and stored in the GLC state machine so we now have to call <a class="el" href="group__measure.html#ga9722aac509be8927b5fb2d10584b74db" title="This command retrieves a string metric from the GLC measurement buffer and stores it in outVec...">glcGetStringMetric()</a> to get the bounding box of the string :</p>
<div class="fragment"><div class="line"><a class="code" href="group__measure.html#ga9722aac509be8927b5fb2d10584b74db">glcGetStringMetric</a>(GLC_BOUNDS, bbox);</div></div><!-- fragment --><p>If we would render the bounding box now, it would be drawn at the wrong location since we do not have taken the advance of the character <em>"H"</em> into account :</p>
<div class="image">
<img src="tutorial2_wrong.png" alt="tutorial2_wrong.png"/>
<div class="caption">
Figure 3 - The bounding box of 'ello' is misplaced</div></div>
<p>Hence we need first to translate the bounding box of the advance of the character <em>"H"</em>. Since the advance of a character is equal to the length of its <em>baseline</em>, the translation must be equal to the vector <img class="formulaInl" alt="$ \left ( \begin {array}{ll} x_r-x_l \\ y_r-y_l \\ \end{array} \right ) $" src="form_3.png"/> according to the notations of the Figure 2.</p>
<dl class="section note"><dt>Note</dt><dd><em>It must be stressed that this formula assumes that the string is rendered in left-to-right order. If you intend to render strings in right-to-left order you must use the opposite of the vector defined above</em>.</dd></dl>
<p>An array of 4 floating point numbers must be used in order to store the coordinates [ x<sub>l</sub> y<sub>l</sub> x<sub>r</sub> y<sub>r</sub> ] of the baseline : </p><div class="fragment"><div class="line">GLfloat baseline[4] = {0.f, 0.f, 0.f, 0.f};</div></div><!-- fragment --><p>Then the baseline of <em>"H"</em> is obtained by calling <a class="el" href="group__measure.html#ga0662d416bafc192517b0155ebba66579" title="This command is identical to the command glcRenderChar(), except that instead of rendering the charac...">glcGetCharMetric()</a> with the second parameter set to <b>GLC_BASELINE</b>. The advance of the character is then computed and added to the <b>GL_MODELVIEW</b> matrix :</p>
<div class="fragment"><div class="line"><span class="comment">// Get the baseline of the character &quot;H&quot;</span></div><div class="line"><a class="code" href="group__measure.html#ga0662d416bafc192517b0155ebba66579">glcGetCharMetric</a>(<span class="charliteral">&#39;H&#39;</span>, GLC_BASELINE, baseline);</div><div class="line"><span class="comment">// Translate the bounding box of the advance of &quot;H&quot;</span></div><div class="line">glTranslatef(baseline[2] - baseline[0], baseline[3] - baseline[1], 0.f);</div></div><!-- fragment --><p>Afterwards the bounding box of <em>"ello"</em> is rendered at the right place :</p>
<div class="fragment"><div class="line"><span class="comment">// Render the bounding box</span></div><div class="line">glBegin(GL_LINE_LOOP);</div><div class="line"><span class="keywordflow">for</span> (i = 0; i &lt; 4; i++)</div><div class="line">  glVertex2fv(&amp;bbox[2*i]);</div><div class="line">glEnd();</div></div><!-- fragment --><h1><a class="anchor" id="conclusion"></a>
Conclusion</h1>
<p>In this tutorial, the basic concepts of character metrics available in GLC have been presented. Although the chosen example is somewhat artificial since there are few chances that you need to display the bounding boxes of a character or a string, it illustrates how the character metrics are handled by GLC and how they should be manipulated.</p>
<p>Character metrics are primarily intended for layout management, although this topic is far beyond the scope of this tutorial, the concepts exposed here are sufficient to handle basic cases like processing the location of a centered string on the screen.</p>
<p>Finally, a program that display the bounding boxes of a character and a string has been elaborated in this tutorial. Its listing is shown hereafter (the commands that bind a GL context to the current thread are not included) :</p>
<div class="fragment"><div class="line">GLint ctx, myFont, i;</div><div class="line">GLfloat bbox[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};</div><div class="line">GLfloat baseline[4] = {0.f, 0.f, 0.f, 0.f};</div><div class="line"></div><div class="line"><span class="comment">// Set up and initialize GLC</span></div><div class="line">ctx = <a class="code" href="group__global.html#ga65c4f22e1a75bca7edafe35fe6b185ee">glcGenContext</a>();</div><div class="line"><a class="code" href="group__global.html#gaaa17c69ee70f9e8a900dc9c6830f3f09">glcContext</a>(ctx);</div><div class="line"><span class="comment">//glcAppendCatalog(&quot;/usr/lib/X11/fonts/Type1&quot;);</span></div><div class="line"></div><div class="line"><span class="comment">// Create a font &quot;Palatino Bold&quot;</span></div><div class="line">myFont = <a class="code" href="group__font.html#ga658c40ba0437274cf2849bc3dac4dd20">glcGenFontID</a>();</div><div class="line"><a class="code" href="group__font.html#gacc8675929261b5f04882d375cb54a530">glcNewFontFromFamily</a>(myFont, <span class="stringliteral">&quot;Palatino&quot;</span>);</div><div class="line"><a class="code" href="group__font.html#gab9800f5153d46bd293b62dc7bfcd364f">glcFontFace</a>(myFont, <span class="stringliteral">&quot;Bold&quot;</span>);</div><div class="line"><a class="code" href="group__font.html#gaab2c8a01997c3827b10aebedd8e78501">glcFont</a>(myFont);</div><div class="line"></div><div class="line"><span class="comment">// Render the text at a size of 100 points</span></div><div class="line"><a class="code" href="group__transform.html#ga71a9a779d35bc8c4631de7cbda21cea6">glcScale</a>(100.f, 100.f);</div><div class="line"><a class="code" href="group__transform.html#ga978d760fac5b11cd876b8c3a0055dadf">glcRotate</a>(10.f); <span class="comment">// Rotate the text of 10 degrees counterclockwise</span></div><div class="line"></div><div class="line"><span class="comment">// Render &quot;Hello world!&quot;</span></div><div class="line">glColor3f(1.f, 0.f, 0.f);</div><div class="line">glRasterPos2f(50.f, 50.f);</div><div class="line"><a class="code" href="group__render.html#ga93708ef20c96fd01019fcd9eb18f0b03">glcRenderString</a>(<span class="stringliteral">&quot;Hello world!&quot;</span>);</div><div class="line"></div><div class="line">glColor3f(0.f, 1.f, 1.f);</div><div class="line"></div><div class="line"><span class="comment">// Render the bounding box of &quot;H&quot;</span></div><div class="line"><a class="code" href="group__measure.html#ga0662d416bafc192517b0155ebba66579">glcGetCharMetric</a>(<span class="charliteral">&#39;H&#39;</span>, GLC_BOUNDS, bbox);</div><div class="line"><span class="comment">// Translate the bbox to the origin of the layout</span></div><div class="line">glTranslatef(50.f, 50.f, 0.f);</div><div class="line"><span class="comment">// Render the bounding box</span></div><div class="line">glBegin(GL_LINE_LOOP);</div><div class="line"><span class="keywordflow">for</span> (i = 0; i &lt; 4; i++)</div><div class="line">  glVertex2fv(&amp;bbox[2*i]);</div><div class="line">glEnd();</div><div class="line"></div><div class="line"><span class="comment">// Translate the origin in order to take the width of &quot;H&quot; into account</span></div><div class="line"><span class="comment">// Get the baseline of the character &quot;H&quot;</span></div><div class="line"><a class="code" href="group__measure.html#ga0662d416bafc192517b0155ebba66579">glcGetCharMetric</a>(<span class="charliteral">&#39;H&#39;</span>, GLC_BASELINE, baseline);</div><div class="line"><span class="comment">// Translate the bounding box of the advance of &quot;H&quot;</span></div><div class="line">glTranslatef(baseline[2] - baseline[0], baseline[3] - baseline[1], 0.f);</div><div class="line"></div><div class="line"><span class="comment">// Render the bounding box of &quot;ello&quot;</span></div><div class="line"><a class="code" href="group__measure.html#ga8c17cf3164f9b45d293704dd511b5e94">glcMeasureString</a>(GL_FALSE, <span class="stringliteral">&quot;ello&quot;</span>);</div><div class="line"><a class="code" href="group__measure.html#ga9722aac509be8927b5fb2d10584b74db">glcGetStringMetric</a>(GLC_BOUNDS, bbox);</div><div class="line"><span class="comment">// Render the bounding box</span></div><div class="line">glBegin(GL_LINE_LOOP);</div><div class="line"><span class="keywordflow">for</span> (i = 0; i &lt; 4; i++)</div><div class="line">  glVertex2fv(&amp;bbox[2*i]);</div><div class="line">glEnd();</div></div><!-- fragment --> </div></div><!-- contents -->
          </td>
	</tr>
        <tr>
          <td align="center" class="main">
	    <hr>
            <small>
              <font color="#cccccc">Generated on Mon Oct 1 2018 06:30:23 for QuesoGLC by <a href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border=0></a> 1.8.14 written by Dimitri van Heesch &copy;&nbsp;1997-2005</font>
            </small>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>
</body>
</html>