1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef GFX_DWRITECOMMON_H
7 #define GFX_DWRITECOMMON_H
8 
9 // Mozilla includes
10 #include "nscore.h"
11 #include "nsIServiceManager.h"
12 #include "nsCOMPtr.h"
13 #include "cairo-features.h"
14 #include "gfxFontConstants.h"
15 #include "nsTArray.h"
16 #include "gfxWindowsPlatform.h"
17 #include "nsIUUIDGenerator.h"
18 
19 #include <windows.h>
20 #include <dwrite.h>
21 
DWriteFontStretchFromStretch(int16_t aStretch)22 static inline DWRITE_FONT_STRETCH DWriteFontStretchFromStretch(
23     int16_t aStretch) {
24   switch (aStretch) {
25     case NS_FONT_STRETCH_ULTRA_CONDENSED:
26       return DWRITE_FONT_STRETCH_ULTRA_CONDENSED;
27     case NS_FONT_STRETCH_EXTRA_CONDENSED:
28       return DWRITE_FONT_STRETCH_EXTRA_CONDENSED;
29     case NS_FONT_STRETCH_CONDENSED:
30       return DWRITE_FONT_STRETCH_CONDENSED;
31     case NS_FONT_STRETCH_SEMI_CONDENSED:
32       return DWRITE_FONT_STRETCH_SEMI_CONDENSED;
33     case NS_FONT_STRETCH_NORMAL:
34       return DWRITE_FONT_STRETCH_NORMAL;
35     case NS_FONT_STRETCH_SEMI_EXPANDED:
36       return DWRITE_FONT_STRETCH_SEMI_EXPANDED;
37     case NS_FONT_STRETCH_EXPANDED:
38       return DWRITE_FONT_STRETCH_EXPANDED;
39     case NS_FONT_STRETCH_EXTRA_EXPANDED:
40       return DWRITE_FONT_STRETCH_EXTRA_EXPANDED;
41     case NS_FONT_STRETCH_ULTRA_EXPANDED:
42       return DWRITE_FONT_STRETCH_ULTRA_EXPANDED;
43     default:
44       return DWRITE_FONT_STRETCH_UNDEFINED;
45   }
46 }
47 
FontStretchFromDWriteStretch(DWRITE_FONT_STRETCH aStretch)48 static inline int16_t FontStretchFromDWriteStretch(
49     DWRITE_FONT_STRETCH aStretch) {
50   switch (aStretch) {
51     case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
52       return NS_FONT_STRETCH_ULTRA_CONDENSED;
53     case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
54       return NS_FONT_STRETCH_EXTRA_CONDENSED;
55     case DWRITE_FONT_STRETCH_CONDENSED:
56       return NS_FONT_STRETCH_CONDENSED;
57     case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
58       return NS_FONT_STRETCH_SEMI_CONDENSED;
59     case DWRITE_FONT_STRETCH_NORMAL:
60       return NS_FONT_STRETCH_NORMAL;
61     case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
62       return NS_FONT_STRETCH_SEMI_EXPANDED;
63     case DWRITE_FONT_STRETCH_EXPANDED:
64       return NS_FONT_STRETCH_EXPANDED;
65     case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
66       return NS_FONT_STRETCH_EXTRA_EXPANDED;
67     case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
68       return NS_FONT_STRETCH_ULTRA_EXPANDED;
69     default:
70       return NS_FONT_STRETCH_NORMAL;
71   }
72 }
73 
74 struct ffReferenceKey {
75   FallibleTArray<uint8_t>* mArray;
76   nsID mGUID;
77 };
78 
79 class gfxDWriteFontFileLoader : public IDWriteFontFileLoader {
80  public:
gfxDWriteFontFileLoader()81   gfxDWriteFontFileLoader() {}
82 
83   // IUnknown interface
IFACEMETHOD(QueryInterface)84   IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) {
85     if (iid == __uuidof(IDWriteFontFileLoader)) {
86       *ppObject = static_cast<IDWriteFontFileLoader*>(this);
87       return S_OK;
88     } else if (iid == __uuidof(IUnknown)) {
89       *ppObject = static_cast<IUnknown*>(this);
90       return S_OK;
91     } else {
92       return E_NOINTERFACE;
93     }
94   }
95 
IFACEMETHOD_(ULONG,AddRef)96   IFACEMETHOD_(ULONG, AddRef)() { return 1; }
97 
IFACEMETHOD_(ULONG,Release)98   IFACEMETHOD_(ULONG, Release)() { return 1; }
99 
100   // IDWriteFontFileLoader methods
101   /**
102    * Important! Note the key here -has- to be a pointer to a uint64_t.
103    */
104   virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(
105       void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize,
106       OUT IDWriteFontFileStream** fontFileStream);
107 
108   /**
109    * Gets the singleton loader instance. Note that when using this font
110    * loader, the key must be a pointer to a unint64_t.
111    */
Instance()112   static IDWriteFontFileLoader* Instance() {
113     if (!mInstance) {
114       mInstance = new gfxDWriteFontFileLoader();
115       mozilla::gfx::Factory::GetDWriteFactory()->RegisterFontFileLoader(
116           mInstance);
117     }
118     return mInstance;
119   }
120 
121   /**
122    * Creates a IDWriteFontFile and IDWriteFontFileStream from aFontData.
123    * The data from aFontData will be copied internally, so the caller
124    * is free to dispose of it once this method returns.
125    *
126    * @param aFontData the font data for the custom font file
127    * @param aLength length of the font data
128    * @param aFontFile out param for the created font file
129    * @param aFontFileStream out param for the corresponding stream
130    * @return HRESULT of internal calls
131    */
132   static HRESULT CreateCustomFontFile(const uint8_t* aFontData,
133                                       uint32_t aLength,
134                                       IDWriteFontFile** aFontFile,
135                                       IDWriteFontFileStream** aFontFileStream);
136 
137  private:
138   static IDWriteFontFileLoader* mInstance;
139 };
140 
141 #endif /* GFX_DWRITECOMMON_H */
142