<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, May 24, 2019 at 8:45 PM Konstantin Ritt <<a href="mailto:ritt.ks@gmail.com">ritt.ks@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi Behdad,</div><div><br></div><div>That was just a glance example of the font table referencing GDI-HB bridge.</div><div>Feel free to use it in hb-<backend> if you like it ;P</div><div><br></div><div>As for font-funcs, I doubt GDI is a subject of interest these days. I might be wrong here, though.</div></div></blockquote><div><br></div><div>I think GDI32 does offer some legacy shaping functionality for Arabic/Hebrew/maybe Hangul, that predates Uniscribe, but I don't think it's very interesting to look at such results.</div><div><br></div><div>Regarding font data access functions, those would be essentially the same as with Uniscribe, because it's directly tied to HDC and GDI font functionality.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br clear="all"><div><div dir="ltr" class="gmail-m_6442266281943516558gmail_signature">Regards,<br>Konstantin</div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">пт, 24 мая 2019 г. в 19:18, Behdad Esfahbod <<a href="mailto:behdad@behdad.org" target="_blank">behdad@behdad.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thanks Konstantin!<div><br></div><div>Should this become a hb-uniscribe (or hb-gdi?) API?</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, May 24, 2019 at 12:17 PM Konstantin Ritt <<a href="mailto:ritt.ks@gmail.com" target="_blank">ritt.ks@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><pre style="margin-top:0px;margin-bottom:0px">hb_blob_t<span style="color:rgb(192,192,192)"> </span>*my_reference_table(hb_face_t<span style="color:rgb(192,192,192)"> </span>*<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">/*face*/</span>,<span style="color:rgb(192,192,192)"> </span>hb_tag_t<span style="color:rgb(192,192,192)"> </span>tag,<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">void</span><span style="color:rgb(192,192,192)"> </span>*user_data)</pre>
<pre style="margin-top:0px;margin-bottom:0px">{</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span>HDC<span style="color:rgb(192,192,192)"> </span>hdc<span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span>(HDC)user_data;</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span>SelectObject(hdc,<span style="color:rgb(192,192,192)"> </span>hfont);</pre>
<pre style="margin-top:0px;margin-bottom:0px"><br></pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">char</span><span style="color:rgb(192,192,192)"> </span>*buffer<span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span>NULL;</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span>DWORD<span style="color:rgb(192,192,192)"> </span>length<span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span>;</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span></pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span>length<span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span>GetFontData(hdc,<span style="color:rgb(192,192,192)"> </span>byte_swap<DWORD>(tag),<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span>,<span style="color:rgb(192,192,192)"> </span>buffer,<span style="color:rgb(192,192,192)"> </span>length);</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">if</span><span style="color:rgb(192,192,192)"> </span>(length<span style="color:rgb(192,192,192)"> </span>==<span style="color:rgb(192,192,192)"> </span>GDI_ERROR)</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">return</span><span style="color:rgb(192,192,192)"> </span>hb_blob_get_empty();</pre>
<pre style="margin-top:0px;margin-bottom:0px"><br></pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span>buffer<span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span>(<span style="color:rgb(128,128,0)">char</span><span style="color:rgb(192,192,192)"> </span>*)::malloc(length);</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span>length<span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span>GetFontData(hdc,<span style="color:rgb(192,192,192)"> </span>byte_swap<DWORD>(tag),<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span>,<span style="color:rgb(192,192,192)"> </span>buffer,<span style="color:rgb(192,192,192)"> </span>length);</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">if</span><span style="color:rgb(192,192,192)"> </span>(length<span style="color:rgb(192,192,192)"> </span>==<span style="color:rgb(192,192,192)"> </span>GDI_ERROR)</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span>length<span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span>;</pre>
<pre style="margin-top:0px;margin-bottom:0px"><br></pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">return</span><span style="color:rgb(192,192,192)"> </span>hb_blob_create((<span style="color:rgb(128,128,0)">const</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">char</span><span style="color:rgb(192,192,192)"> </span>*)buffer,<span style="color:rgb(192,192,192)"> </span>length,<span style="color:rgb(192,192,192)"> </span>HB_MEMORY_MODE_READONLY,<span style="color:rgb(192,192,192)"> </span>buffer<span style="color:rgb(128,128,0)">, ::fr</span>e<span style="color:rgb(128,128,0)">e);</span></pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(128,128,0)">}</span></pre>
<pre style="margin-top:0px;margin-bottom:0px;color:rgb(128,128,0)"><br></pre>
<pre style="margin-top:0px;margin-bottom:0px">hb_face_t<span style="color:rgb(192,192,192)"> </span>*my_face_create_from_hdc(HDC<span style="color:rgb(192,192,192)"> </span>hdc)</pre>
<pre style="margin-top:0px;margin-bottom:0px">{</pre>
<pre style="margin-top:0px;margin-bottom:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">return</span><span style="color:rgb(192,192,192)"> </span>hb_face_create_for_tables(my_reference_table,<span style="color:rgb(192,192,192)"> </span>(<span style="color:rgb(128,128,0)">void</span><span style="color:rgb(192,192,192)"> </span>*)hdc,<span style="color:rgb(192,192,192)"> </span>NULL);</pre>
<pre style="margin-top:0px;margin-bottom:0px">}</pre></div><div><br></div><div><br></div><br clear="all"><div><div dir="ltr" class="gmail-m_6442266281943516558gmail-m_-8102750311025013796gmail-m_1729726368139753960gmail_signature">Regards,<br>Konstantin</div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">пт, 24 мая 2019 г. в 16:39, Eli Zaretskii <<a href="mailto:eliz@gnu.org" target="_blank">eliz@gnu.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">> From: Ebrahim Byagowi <<a href="mailto:ebraminio@gmail.com" target="_blank">ebraminio@gmail.com</a>><br>
> Date: Fri, 24 May 2019 20:13:43 +0430<br>
> Cc: Harfbuzz <<a href="mailto:harfbuzz@lists.freedesktop.org" target="_blank">harfbuzz@lists.freedesktop.org</a>><br>
> <br>
> Pardon me for the may inaccurate following answer I have to write quickly,<br>
<br>
Thanks for your help.<br>
<br>
> > Also, does HarfBuzz support TrueType Collection (TTC) files, and if so, does it want the data only for the<br>
> currently selected font or all<br>
> of the data?<br>
> <br>
> It does, if you want harfbuzz handles it for you, you should give it the full blob and set the index you like in<br>
> second argument of hb_face_create, otherwise you should handle it yourself.<br>
<br>
OK, this brings me to another question: what should I in general pass<br>
as the 2nd argument of hb_face_create? Suppose I'm using a TTF or OTF<br>
font file, should I always pass zero as the 2nd argument? What is the<br>
semantics of that argument?<br>
<br>
> > I'm now working on the HarfBuzz font driver for Emacs on Windows using GetFontData with the dwTable<br>
> argument zero, to get the entire data of the font.<br>
> <br>
> Is it DirectWrite? Have you seen the helper we have the in hb-directwrite.h and hb-uniscribe.h? They can be<br>
> very useful.<br>
<br>
I'm not using DirectWrite, nor am I using Uniscribe. My HarfBuzz is<br>
built without these two, as I understand building with these back-ends<br>
is only needed for comparison. I want to use the HarfBuzz shaper, and<br>
only it (Emacs already has support for Uniscribe).<br>
<br>
But yes, I do consult these files to figure out answers to my<br>
questions.<br>
<br>
> > does their memory need to be freed in some manner after I have the hb_font_t object, or do I have to keep<br>
> them as long as hb_font_t is in use? <br>
> <br>
> Don't free it yourself specially if in use, you can use harfbuzz destroy callback so harfbuzz can handle it for<br>
> you.<br>
<br>
Sorry, I don't think I understand: what do you mean by "harfbuzz<br>
destroy callback"? If you mean the 'destroy" argument of<br>
hb_blob_create, then AFAIU this is called only to destroy user_data,<br>
and I don't have user_data, I pass NULL as the 4th argument of<br>
hb_blob_create. And hb_face_create doesn't have any callback argument<br>
at all.<br>
<br>
I see in the few programs in util/ that both the blob and the face are<br>
destroyed as soon as hb_font_t object is created, which is why I<br>
thought I could do the same. But now you seem to say I shouldn't?<br>
<br>
For that matter, what should I use as the 'mode' argument of<br>
hb_blob_create?<br>
<br>
This page:<br>
<br>
<a href="https://harfbuzz.github.io/object-model-blobs.html" rel="noreferrer" target="_blank">https://harfbuzz.github.io/object-model-blobs.html</a><br>
<br>
shows an example of calling hb_blob_create with 'free' (in my case,<br>
'xfree') as the 'destroy' callback, so I guess my interpretation of<br>
that argument as being pertinent to user_data was incorrect? Still,<br>
the questions about memory management for hb_face_t and about the<br>
semantics of the hb_memory_mode_t enum values are left unanswered.<br>
<br>
> > I see that hb_blob_create, hb_face_create etc. return empty objects when they fail. But I see no "is-empty"<br>
> function or macro in the docs, did I miss something?<br>
> <br>
> Some of the objects may work with empty comparison but it is not broken face<br>
> <a href="https://github.com/harfbuzz/harfbuzz/issues/1572" rel="noreferrer" target="_blank">https://github.com/harfbuzz/harfbuzz/issues/1572</a> but something does it very accurately is<br>
> hb_face_get_glyph_count<br>
<br>
AFAIU, you are saying that if hb_face_get_glyph_count returns zero,<br>
the face is empty and shouldn't be used, is that right?<br>
<br>
> > Where do those 64.0 factors come from? <br>
> <br>
> Subpixel accuracy, harfbuzz works with integers but as subpixel accuracy needed you have to we need to do<br>
> some scaling. Scaling is not the pixels but _set_ppem and _set_ptem is (this is very inaccurate, but I hope<br>
> would be useful)<br>
<br>
Does this mean I should use the factor of 64 in my code as well? Or<br>
does that value depend on some properties of the font?<br>
<br>
> <br>
> > Or point me to the documentation where that is described, if I missed it?<br>
> <br>
> <a href="https://harfbuzz.github.io/" rel="noreferrer" target="_blank">https://harfbuzz.github.io/</a> may address some of your issues<br>
<br>
Thanks again for your help.<br>
_______________________________________________<br>
HarfBuzz mailing list<br>
<a href="mailto:HarfBuzz@lists.freedesktop.org" target="_blank">HarfBuzz@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/harfbuzz" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/harfbuzz</a></blockquote></div>
_______________________________________________<br>
HarfBuzz mailing list<br>
<a href="mailto:HarfBuzz@lists.freedesktop.org" target="_blank">HarfBuzz@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/harfbuzz" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/harfbuzz</a></blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail-m_6442266281943516558gmail-m_-8102750311025013796gmail_signature">behdad<br><a href="http://behdad.org/" target="_blank">http://behdad.org/</a></div>
</blockquote></div>
_______________________________________________<br>
HarfBuzz mailing list<br>
<a href="mailto:HarfBuzz@lists.freedesktop.org" target="_blank">HarfBuzz@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/harfbuzz" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/harfbuzz</a></blockquote></div></div>