<div dir="ltr"><div>Hi guys,<br></div><div><br></div><div>There is yet another issue left out of the scope: </div><div>hb_position_t is a typedef of int32_t, you know, and to avoid float-to-integer truncation the proposed solution was to specify scale factor shifted left.</div>
<div>For example to make all results in 26.6 float format, scale shall be shifted 6 bits left and then the result must be divided to 64.0 to get the original float (well, almost original but 6 digit after the point is quite enough for all use-cases).</div>
<div>However, the scale factor applied to results in OT shaper only, the other shapers doesn't respect the scale factor and truncation may occur there (i.e. double advance = ..; pos->x_advance = advance;). This also leads to unexpected results since 1) pos->x_advance / 64.0 ~= 0 and 2) CTFontCreateWithGraphicsFont (face_data->cg_font, font->y_scale, NULL, NULL) falls back to pointSize=12 when y_scale is out of bounds. (BTW, what ppem is for, then?)</div>
<div><br></div><div>I'd propose change hb_position_t to be in 26.6 float format everywhere and explicitly mention that in the docs. This would guarantee an expected/unified results for any shaper, w/o having to do some tricky scaling.</div>
<div>We could also want to introduce an API to fine-tune the hinting preference, so that all metrics would be either in design units or in hinted advances (after a brief review, it looks like it isn't possible to achieve that on client side only).</div>
<div><br></div><div>Correct me if I'm wrong.</div><div><br></div><div>Best regards,<br>Konstantin
<br><br><div class="gmail_quote">2014/1/6 Konstantin Ritt <span dir="ltr"><<a href="mailto:ritt.ks@gmail.com" target="_blank">ritt.ks@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div><div class="h5"><br><div class="gmail_quote">2014/1/6 Khaled Hosny <span dir="ltr"><<a href="mailto:khaledhosny@eglug.org" target="_blank">khaledhosny@eglug.org</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Another thing that I’d like to see sorted before the API is finalised,<br>
is reverse mapping of output glyphs to input characters with proper<br>
handling of combing marks. I feel we should keep the current cluster<br>
stuff since it might have its uses (I’m not sure though) and introduce a<br>
separate way for that mapping. Either way, I think a more indicative<br>
name would be better (it took me sometime to understand what those<br>
clusters are for and they mislead me quit a bit when I tried to use<br>
HarfBuzz for the first time).<br>
<br>
Regards,<br>
Khaled<br>
</blockquote></div><div><br></div></div></div><div>Oh, I thought I'm the only one who felt into that trouble :)</div><div><br></div><div>Here is a result of my tries and fails:</div><div><span style="color:#c0c0c0">[code]<br>
</span></div>
<div>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span>ushort<span style="color:#c0c0c0"> </span><span>*</span>log_clusters<span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span>...<span>;<br>
</span><span style="color:#c0c0c0"> </span><span style="color:#808000">const</span><span style="color:#c0c0c0"> </span>uint<span style="color:#c0c0c0"> </span>num_glyphs<span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span>hb_buffer_get_length<span>(</span>buffer<span>);<br>
</span><span style="color:#c0c0c0"> </span>hb_glyph_info_t<span style="color:#c0c0c0"> </span><span>*</span>infos<span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span>hb_buffer_get_glyph_infos<span>(</span>buffer<span>,</span><span style="color:#c0c0c0"> </span><span style="color:#000080">0</span><span>);</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span style="color:#808000">for</span><span style="color:#c0c0c0"> </span><span>(</span>uint<span style="color:#c0c0c0"> </span>i<span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span><span style="color:#000080">0</span><span>;</span><span style="color:#c0c0c0"> </span>i<span style="color:#c0c0c0"> </span><span><</span><span style="color:#c0c0c0"> </span>num_glyphs<span>;</span><span style="color:#c0c0c0"> </span><span>++</span>i<span>)</span><span style="color:#c0c0c0"> </span><span>{</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span>log_clusters<span>[</span>i<span>]</span><span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span>infos<span>[</span>i<span>].</span>cluster<span>;<br>
// ... </span>glyphs<span>[</span>i<span>]</span><span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span>infos<span>[</span>i<span>].</span>codepoint; and so on<br>
<span style="color:#c0c0c0"> </span><span>}</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><br></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span style="color:#008000">//</span><span style="color:#c0c0c0"> </span><span style="color:#008000">adjust</span><span style="color:#c0c0c0"> </span><span style="color:#008000">clusters</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span>uint<span style="color:#c0c0c0"> </span>glyph_pos<span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span><span style="color:#000080">0</span><span>;</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span style="color:#808000">for</span><span style="color:#c0c0c0"> </span><span>(</span>uint<span style="color:#c0c0c0"> </span>i<span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span><span style="color:#000080">0</span><span>;</span><span style="color:#c0c0c0"> </span>i<span style="color:#c0c0c0"> </span><span><</span> num_characters;<span style="color:#c0c0c0"> </span><span>++</span>i<span>)</span><span style="color:#c0c0c0"> </span><span>{</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span style="color:#808000">if</span><span style="color:#c0c0c0"> </span><span>(i</span><span style="color:#c0c0c0"> </span><span>!=</span><span style="color:#c0c0c0"> </span>infos<span>[</span>glyph_pos<span>].</span>cluster<span>)</span><span style="color:#c0c0c0"> </span><span>{</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span style="color:#808000">for</span><span style="color:#c0c0c0"> </span><span>(</span>uint<span style="color:#c0c0c0"> </span>j<span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span>glyph_pos<span style="color:#c0c0c0"> </span><span>+</span><span style="color:#c0c0c0"> </span><span style="color:#000080">1</span><span>;</span><span style="color:#c0c0c0"> </span>j<span style="color:#c0c0c0"> </span><span><</span><span style="color:#c0c0c0"> </span>num_glyphs<span>;</span><span style="color:#c0c0c0"> </span><span>++</span>j<span>)</span><span style="color:#c0c0c0"> </span><span>{</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span style="color:#808000">if</span><span style="color:#c0c0c0"> </span><span>(</span>i<span style="color:#c0c0c0"> </span><span><=</span><span style="color:#c0c0c0"> </span>infos<span>[</span>j<span>].</span>cluster<span>)</span><span style="color:#c0c0c0"> </span><span>{</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span style="color:#808000">if</span><span style="color:#c0c0c0"> </span><span>(</span>i<span style="color:#c0c0c0"> </span><span>==</span><span style="color:#c0c0c0"> </span>infos<span>[</span>j<span>].</span>cluster<span>)</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span>glyph_pos<span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span>j<span>;</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span style="color:#808000">break</span><span>;</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span>}</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span>}</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span>}</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span>log_clusters<span>[</span>i<span>]</span><span style="color:#c0c0c0"> </span><span>=</span><span style="color:#c0c0c0"> </span>glyph_pos<span>;</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px"><span style="color:#c0c0c0"> </span><span>}</span></pre></div><div>
<span style="color:#c0c0c0">[/code]</span>
<br><div class="gmail_extra"><br clear="all"><div>You could agree that the latter part is not obvious.</div><div>And except of bringing some inconvenience to the user, lack of reverse mapping API also hits the performance a bit since we can not avoid this loop with "if (num_glyphs != num_characters)".</div>
<div><br></div><div>Regards,<br>Konstantin</div></div><br></div></div>
</blockquote></div><br></div></div>