[HarfBuzz] DirectWrite backend for HarfBuzz

Nikolay Sivov bunglehead at gmail.com
Fri Sep 11 00:11:35 PDT 2015


On 11.09.2015 9:11, Ebrahim Byagowi wrote:
>   * It uses DirectWrite GDI Interop instead IDWriteFontFileStream
>     <https://github.com/servo/skia/blob/master/src/utils/win/SkDWriteFontFileStream.h>
>     for loading the font (and many parts of the patch is actually copied
>     from uniscribe backend)

The only reason to use GdiInterop is to enable GDI font 
substitution/resolution. If you don't need that dwrite way would be to 
get system font collection, locate family by name, and use 
GetFirstMatchingFont() with desired weight/style/stretch triple.


  > +  hr = analyzer->GetGlyphs(pchars, length,
> +    fontFace, FALSE,
> +    buffer->props.direction,
> +    &runHead->mScript, NULL, NULL, NULL, NULL, 0,
> +    maxGlyphs, clusters, textProperties,
> +    glyphs, glyphProperties, &actualGlyphs);
> +
> +  if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
> +    return false;
> +  }

When this fails like that you need to reallocate with returned 
actualGlyphs, and call GetGlyphs again.


> +  unsigned int chars_len = 0;
> +  for (unsigned int i = 0; i < buffer->len; i++)
> +  {
> +    hb_codepoint_t c = buffer->info[i].codepoint;
> +    buffer->info[i].utf16_index() = chars_len;
> +    if (likely(c <= 0xFFFFu))
> +      pchars[chars_len++] = c;
> +    else if (unlikely(c > 0x10FFFFu))
> +      pchars[chars_len++] = 0xFFFDu;
> +    else {
> +      pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
> +      pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1));
> +    }
> +  }

Why do you need this? Dwrite input is supposed to be in WCHARs.

> +  const wchar_t* mText;
> +  const wchar_t* mLocaleName;

This should use WCHAR or similar-sized type - wchar_t size is variable.


> uint32_t appUnitsPerDevPixel = 72;

This is not used. Note that returned advances/offsets are scaled with:

<design advance> * emSize / designUnitsPerEm.

> +  hr = analyzer->GetGlyphs(pchars, length,
> +    fontFace, FALSE,
> +    buffer->props.direction,
> +    &runHead->mScript, NULL, NULL, NULL, NULL, 0,
> +    maxGlyphs, clusters, textProperties,
> +    glyphs, glyphProperties, &actualGlyphs);

How can this work if you never pass run text to it? Not to mention 
locale. Also looks like you only try with runHead, so the rest of runs 
are ignored?

>   * It may has some more minor and major issues which I didn't remember
>     to note :)
>
> While I am not a Windows programmer and also also not being familiar
> with DirectWrite and even DirectX development, the motivation for me was
> just to have access to DirectWrite specific capabilities (explicitly,
> Kashida justification
> <https://msdn.microsoft.com/en-us/library/windows/desktop/hh994452(v=vs.85).aspx#Justification>)
> in hope the features would be developed inside harfbuzz someday (this
> can be accessed on Uniscribe backend, ScriptJustify
> <https://maxradi.us/documents/uniscribe/#ScriptJustify> which I probably
> would dig more if I see there would not any possible progress on this
> approach). This patch is far from prefect but I just hoped this would be
> useful for someone someday or would be merged on HarfBuzz :)
>
>
> _______________________________________________
> HarfBuzz mailing list
> HarfBuzz at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/harfbuzz
>



More information about the HarfBuzz mailing list