smourier / DirectN

Direct interop Code for .NET Framework, .NET Core and .NET 5+ : DXGI, WIC, DirectX 9 to 12, Direct2D, Direct Write, Direct Composition, Media Foundation, WASAPI, CodecAPI, GDI, Spatial Audio, DVD, Windows Media Player, UWP DXInterop, WinUI3, etc.
MIT License
311 stars 28 forks source link

Registering remote font file loader #21

Closed miquik closed 2 years ago

miquik commented 2 years ago

Hi, Sorry I'm here again with another problem. I follow this tutorial creating-a-custom-font-set-using-known-remote-fonts-on-the-web and everything is working except one step. I successfully created an instance of IDWriteRemoteFontFileLoader (which inherit from IDWriteFontFileLoader), now i have to register it (step 4) using IDWriteFactory.RegisterFontFileLoader which require an IDWriteFontFileLoader as param. Should work if I pass the instance IDWriteRemoteFontFileLoader but, instead, I receive an invalid cast exception.

I don't know if I'm doing something wrong or there is a bug

Thanks

smourier commented 2 years ago

Hi,

Do you have any code to show? Also .NET's invalid cast exception can sometime find its origin in an underlying E_NOINTERFACE COM error, which can be a threading issue (not using an object in the same thread where it was created)

miquik commented 2 years ago

Here's my minimal code that reproduce that error

  using (var coref = DWriteFunctions.DWriteCreateFactory<IDWriteFactory7>())
  {
      hr = coref.Object.CreateHttpFontFileLoader(null, null, out IDWriteRemoteFontFileLoader newLoader);
      hr = coref.Object.RegisterFontFileLoader(newLoader);
      // do something
  }

This gives me invalid cast exception

smourier commented 2 years ago

This is very strange. I have no idea why it fails. It seems internal to .NET. I've checked the interface guids and definition dozen times and I don't see any issue...

What you can test is something like this:

  using (var coref = DWriteFunctions.DWriteCreateFactory<IDWriteFactory7>())
  {
      hr = coref.Object.CreateHttpFontFileLoader(null, null, out IDWriteRemoteFontFileLoader newLoader);

      var wrapper = new Wrapper(newLoader);
      hr = coref.Object.RegisterFontFileLoader(wrapper);
      // do something
  }

class Wrapper : IDWriteFontFileLoader
{
    private IDWriteRemoteFontFileLoader _loader;

    public Wrapper(IDWriteRemoteFontFileLoader loader)
    {
        _loader = loader;
    }

    public HRESULT CreateStreamFromKey(IntPtr fontFileReferenceKey, uint fontFileReferenceKeySize, out IDWriteFontFileStream fontFileStream)
    {
        return _loader.CreateStreamFromKey(fontFileReferenceKey, fontFileReferenceKeySize, out fontFileStream);
    }
}

see if it works around the issue.

miquik commented 2 years ago

Your workaround seems to work; at least I can execute RegisterFontFileLoader without exception. I also try IDWriteInMemoryFontFileLoader interface and it also works. Maybe there is some internal error in IDWriteRemoteFontFileLoader. I ends up I have probably to implement my own custom RemoteFontLoader

Thanks