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 
22 static inline DWRITE_FONT_STRETCH
DWriteFontStretchFromStretch(int16_t aStretch)23 DWriteFontStretchFromStretch(int16_t aStretch)
24 {
25     switch (aStretch) {
26         case NS_FONT_STRETCH_ULTRA_CONDENSED:
27             return DWRITE_FONT_STRETCH_ULTRA_CONDENSED;
28         case NS_FONT_STRETCH_EXTRA_CONDENSED:
29             return DWRITE_FONT_STRETCH_EXTRA_CONDENSED;
30         case NS_FONT_STRETCH_CONDENSED:
31             return DWRITE_FONT_STRETCH_CONDENSED;
32         case NS_FONT_STRETCH_SEMI_CONDENSED:
33             return DWRITE_FONT_STRETCH_SEMI_CONDENSED;
34         case NS_FONT_STRETCH_NORMAL:
35             return DWRITE_FONT_STRETCH_NORMAL;
36         case NS_FONT_STRETCH_SEMI_EXPANDED:
37             return DWRITE_FONT_STRETCH_SEMI_EXPANDED;
38         case NS_FONT_STRETCH_EXPANDED:
39             return DWRITE_FONT_STRETCH_EXPANDED;
40         case NS_FONT_STRETCH_EXTRA_EXPANDED:
41             return DWRITE_FONT_STRETCH_EXTRA_EXPANDED;
42         case NS_FONT_STRETCH_ULTRA_EXPANDED:
43             return DWRITE_FONT_STRETCH_ULTRA_EXPANDED;
44         default:
45             return DWRITE_FONT_STRETCH_UNDEFINED;
46     }
47 }
48 
49 static inline int16_t
FontStretchFromDWriteStretch(DWRITE_FONT_STRETCH aStretch)50 FontStretchFromDWriteStretch(DWRITE_FONT_STRETCH aStretch)
51 {
52     switch (aStretch) {
53         case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
54             return NS_FONT_STRETCH_ULTRA_CONDENSED;
55         case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
56             return NS_FONT_STRETCH_EXTRA_CONDENSED;
57         case DWRITE_FONT_STRETCH_CONDENSED:
58             return NS_FONT_STRETCH_CONDENSED;
59         case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
60             return NS_FONT_STRETCH_SEMI_CONDENSED;
61         case DWRITE_FONT_STRETCH_NORMAL:
62             return NS_FONT_STRETCH_NORMAL;
63         case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
64             return NS_FONT_STRETCH_SEMI_EXPANDED;
65         case DWRITE_FONT_STRETCH_EXPANDED:
66             return NS_FONT_STRETCH_EXPANDED;
67         case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
68             return NS_FONT_STRETCH_EXTRA_EXPANDED;
69         case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
70             return NS_FONT_STRETCH_ULTRA_EXPANDED;
71         default:
72             return NS_FONT_STRETCH_NORMAL;
73     }
74 }
75 
76 struct ffReferenceKey
77 {
78     FallibleTArray<uint8_t> *mArray;
79     nsID mGUID;
80 };
81 
82 class gfxDWriteFontFileLoader : public IDWriteFontFileLoader
83 {
84 public:
gfxDWriteFontFileLoader()85     gfxDWriteFontFileLoader()
86     {
87     }
88 
89     // IUnknown interface
IFACEMETHOD(QueryInterface)90     IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject)
91     {
92         if (iid == __uuidof(IDWriteFontFileLoader)) {
93             *ppObject = static_cast<IDWriteFontFileLoader*>(this);
94             return S_OK;
95         } else if (iid == __uuidof(IUnknown)) {
96             *ppObject = static_cast<IUnknown*>(this);
97             return S_OK;
98         } else {
99             return E_NOINTERFACE;
100         }
101     }
102 
IFACEMETHOD_(ULONG,AddRef)103     IFACEMETHOD_(ULONG, AddRef)()
104     {
105         return 1;
106     }
107 
IFACEMETHOD_(ULONG,Release)108     IFACEMETHOD_(ULONG, Release)()
109     {
110         return 1;
111     }
112 
113     // IDWriteFontFileLoader methods
114     /**
115      * Important! Note the key here -has- to be a pointer to a uint64_t.
116      */
117     virtual HRESULT STDMETHODCALLTYPE
118         CreateStreamFromKey(void const* fontFileReferenceKey,
119                             UINT32 fontFileReferenceKeySize,
120                             OUT IDWriteFontFileStream** fontFileStream);
121 
122     /**
123      * Gets the singleton loader instance. Note that when using this font
124      * loader, the key must be a pointer to a unint64_t.
125      */
Instance()126     static IDWriteFontFileLoader* Instance()
127     {
128         if (!mInstance) {
129             mInstance = new gfxDWriteFontFileLoader();
130             gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()->
131                 RegisterFontFileLoader(mInstance);
132         }
133         return mInstance;
134     }
135 
136     /**
137      * Creates a IDWriteFontFile and IDWriteFontFileStream from aFontData.
138      * aFontData will be empty on return as it swaps out the data.
139      *
140      * @param aFontData the font data for the custom font file
141      * @param aFontFile out param for the created font file
142      * @param aFontFileStream out param for the corresponding stream
143      * @return HRESULT of internal calls
144      */
145     static HRESULT CreateCustomFontFile(FallibleTArray<uint8_t>& aFontData,
146                                         IDWriteFontFile** aFontFile,
147                                         IDWriteFontFileStream** aFontFileStream);
148 
149 private:
150     static IDWriteFontFileLoader* mInstance;
151 };
152 
153 #endif /* GFX_DWRITECOMMON_H */
154