tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hb-directwrite.hh (5725B)


      1 /*
      2 *  This is part of HarfBuzz, a text shaping library.
      3 *
      4 * Permission is hereby granted, without written agreement and without
      5 * license or royalty fees, to use, copy, modify, and distribute this
      6 * software and its documentation for any purpose, provided that the
      7 * above copyright notice and the following two paragraphs appear in
      8 * all copies of this software.
      9 *
     10 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     11 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     12 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     13 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     14 * DAMAGE.
     15 *
     16 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     17 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     18 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     19 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     20 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     21 *
     22 * Author(s): Behdad Esfahbod
     23 */
     24 
     25 
     26 #ifndef HB_DIRECTWRITE_HH
     27 #define HB_DIRECTWRITE_HH
     28 
     29 #include "hb.hh"
     30 
     31 #include "hb-directwrite.h"
     32 
     33 #include "hb-mutex.hh"
     34 #include "hb-map.hh"
     35 
     36 /*
     37 * DirectWrite font stream helpers
     38 */
     39 
     40 // Have a look at to NativeFontResourceDWrite.cpp in Mozilla
     41 
     42 
     43 /* Declare object creator for dynamic support of DWRITE */
     44 typedef HRESULT (WINAPI *t_DWriteCreateFactory)(
     45  DWRITE_FACTORY_TYPE factoryType,
     46  REFIID              iid,
     47  IUnknown            **factory
     48 );
     49 
     50 class DWriteFontFileLoader : public IDWriteFontFileLoader
     51 {
     52 private:
     53  hb_reference_count_t mRefCount;
     54  hb_mutex_t mutex;
     55  hb_hashmap_t<uint64_t, IDWriteFontFileStream *> mFontStreams;
     56  uint64_t mNextFontFileKey = 0;
     57 public:
     58  DWriteFontFileLoader ()
     59  {
     60    mRefCount.init ();
     61  }
     62 
     63  uint64_t RegisterFontFileStream (IDWriteFontFileStream *fontFileStream)
     64  {
     65    fontFileStream->AddRef ();
     66    hb_lock_t lock {mutex};
     67    mFontStreams.set (mNextFontFileKey, fontFileStream);
     68    return mNextFontFileKey++;
     69  }
     70  void UnregisterFontFileStream (uint64_t fontFileKey)
     71  {
     72    hb_lock_t lock {mutex};
     73    IDWriteFontFileStream *stream = mFontStreams.get (fontFileKey);
     74    if (stream)
     75    {
     76      mFontStreams.del (fontFileKey);
     77      stream->Release ();
     78    }
     79  }
     80 
     81  // IUnknown interface
     82  IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject)
     83  { return S_OK; }
     84  IFACEMETHOD_ (ULONG, AddRef) ()
     85  {
     86    return mRefCount.inc () + 1;
     87  }
     88  IFACEMETHOD_ (ULONG, Release) ()
     89  {
     90    signed refCount = mRefCount.dec () - 1;
     91    assert (refCount >= 0);
     92    if (refCount)
     93      return refCount;
     94    delete this;
     95    return 0;
     96  }
     97 
     98  // IDWriteFontFileLoader methods
     99  virtual HRESULT STDMETHODCALLTYPE
    100  CreateStreamFromKey (void const* fontFileReferenceKey,
    101 	       uint32_t fontFileReferenceKeySize,
    102 	       OUT IDWriteFontFileStream** fontFileStream)
    103  {
    104    if (fontFileReferenceKeySize != sizeof (uint64_t))
    105      return E_INVALIDARG;
    106    uint64_t fontFileKey = * (uint64_t *) fontFileReferenceKey;
    107    IDWriteFontFileStream *stream = mFontStreams.get (fontFileKey);
    108    if (!stream)
    109      return E_FAIL;
    110    stream->AddRef ();
    111    *fontFileStream = stream;
    112    return S_OK;
    113  }
    114 
    115  virtual ~DWriteFontFileLoader()
    116  {
    117    for (auto v : mFontStreams.values ())
    118      v->Release ();
    119  }
    120 };
    121 
    122 class DWriteFontFileStream : public IDWriteFontFileStream
    123 {
    124 private:
    125  hb_reference_count_t mRefCount;
    126  hb_blob_t *mBlob;
    127  uint8_t *mData;
    128  unsigned mSize;
    129  DWriteFontFileLoader *mLoader;
    130 public:
    131  uint64_t fontFileKey;
    132 public:
    133  DWriteFontFileStream (hb_blob_t *blob);
    134 
    135  // IUnknown interface
    136  IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject)
    137  { return S_OK; }
    138  IFACEMETHOD_ (ULONG, AddRef) ()
    139  {
    140    return mRefCount.inc () + 1;
    141  }
    142  IFACEMETHOD_ (ULONG, Release) ()
    143  {
    144    signed refCount = mRefCount.dec () - 1;
    145    assert (refCount >= 0);
    146    if (refCount)
    147      return refCount;
    148    delete this;
    149    return 0;
    150  }
    151 
    152  // IDWriteFontFileStream methods
    153  virtual HRESULT STDMETHODCALLTYPE
    154  ReadFileFragment (void const** fragmentStart,
    155 	    UINT64 fileOffset,
    156 	    UINT64 fragmentSize,
    157 	    OUT void** fragmentContext)
    158  {
    159    // We are required to do bounds checking.
    160    if (fileOffset + fragmentSize > mSize) return E_FAIL;
    161 
    162    // truncate the 64 bit fileOffset to size_t sized index into mData
    163    size_t index = static_cast<size_t> (fileOffset);
    164 
    165    // We should be alive for the duration of this.
    166    *fragmentStart = &mData[index];
    167    *fragmentContext = nullptr;
    168    return S_OK;
    169  }
    170 
    171  virtual void STDMETHODCALLTYPE
    172  ReleaseFileFragment (void* fragmentContext) {}
    173 
    174  virtual HRESULT STDMETHODCALLTYPE
    175  GetFileSize (OUT UINT64* fileSize)
    176  {
    177    *fileSize = mSize;
    178    return S_OK;
    179  }
    180 
    181  virtual HRESULT STDMETHODCALLTYPE
    182  GetLastWriteTime (OUT UINT64* lastWriteTime) { return E_NOTIMPL; }
    183 
    184  virtual ~DWriteFontFileStream();
    185 };
    186 
    187 struct hb_directwrite_global_t
    188 {
    189  hb_directwrite_global_t ()
    190  {
    191    HRESULT hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
    192 			      (IUnknown**) &dwriteFactory);
    193 
    194    if (unlikely (hr != S_OK))
    195      return;
    196 
    197    fontFileLoader = new DWriteFontFileLoader ();
    198    dwriteFactory->RegisterFontFileLoader (fontFileLoader);
    199 
    200    success = true;
    201  }
    202  ~hb_directwrite_global_t ()
    203  {
    204    if (fontFileLoader)
    205      fontFileLoader->Release ();
    206    if (dwriteFactory)
    207      dwriteFactory->Release ();
    208  }
    209 
    210  bool success = false;
    211  IDWriteFactory *dwriteFactory;
    212  DWriteFontFileLoader *fontFileLoader;
    213 };
    214 
    215 
    216 HB_INTERNAL hb_directwrite_global_t *
    217 get_directwrite_global ();
    218 
    219 HB_INTERNAL IDWriteFontFace *
    220 dw_face_create (hb_blob_t *blob, unsigned index);
    221 
    222 
    223 #endif /* HB_DIRECTWRITE_HH */