Bug 1891710: part 2) Enable <Element-outerHTML.html> WPT for Trusted Types. r=smaug
[gecko.git] / gfx / src / nsThebesFontEnumerator.cpp
blobbaf8c50142c2fa28f45171652524e681e1f9ec5f
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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/. */
6 #include "nsThebesFontEnumerator.h"
7 #include <stdint.h> // for uint32_t
8 #include "gfxPlatform.h" // for gfxPlatform
9 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
10 #include "mozilla/UniquePtr.h"
11 #include "mozilla/dom/Promise.h" // for mozilla::dom::Promise
12 #include "nsCOMPtr.h" // for nsCOMPtr
13 #include "nsDebug.h" // for NS_ENSURE_ARG_POINTER
14 #include "nsError.h" // for NS_OK, NS_FAILED, nsresult
15 #include "nsAtom.h" // for nsAtom, NS_Atomize
16 #include "nsID.h"
17 #include "nsString.h" // for nsAutoCString, nsAutoString, etc
18 #include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc
19 #include "nscore.h" // for char16_t, NS_IMETHODIMP
21 using mozilla::MakeUnique;
22 using mozilla::Runnable;
23 using mozilla::UniquePtr;
25 NS_IMPL_ISUPPORTS(nsThebesFontEnumerator, nsIFontEnumerator)
27 nsThebesFontEnumerator::nsThebesFontEnumerator() = default;
29 NS_IMETHODIMP
30 nsThebesFontEnumerator::EnumerateAllFonts(nsTArray<nsString>& aResult) {
31 return EnumerateFonts(nullptr, nullptr, aResult);
34 NS_IMETHODIMP
35 nsThebesFontEnumerator::EnumerateFonts(const char* aLangGroup,
36 const char* aGeneric,
37 nsTArray<nsString>& aResult) {
38 nsAutoCString generic;
39 if (aGeneric)
40 generic.Assign(aGeneric);
41 else
42 generic.SetIsVoid(true);
44 RefPtr<nsAtom> langGroupAtom;
45 if (aLangGroup) {
46 nsAutoCString lowered;
47 lowered.Assign(aLangGroup);
48 ToLowerCase(lowered);
49 langGroupAtom = NS_Atomize(lowered);
52 return gfxPlatform::GetPlatform()->GetFontList(langGroupAtom, generic,
53 aResult);
56 struct EnumerateFontsPromise final {
57 explicit EnumerateFontsPromise(mozilla::dom::Promise* aPromise)
58 : mPromise(aPromise) {
59 MOZ_ASSERT(aPromise);
60 MOZ_ASSERT(NS_IsMainThread());
63 RefPtr<mozilla::dom::Promise> mPromise;
66 class EnumerateFontsResult final : public Runnable {
67 public:
68 EnumerateFontsResult(nsresult aRv,
69 UniquePtr<EnumerateFontsPromise> aEnumerateFontsPromise,
70 nsTArray<nsString> aFontList)
71 : Runnable("EnumerateFontsResult"),
72 mRv(aRv),
73 mEnumerateFontsPromise(std::move(aEnumerateFontsPromise)),
74 mFontList(std::move(aFontList)),
75 mWorkerThread(do_GetCurrentThread()) {
76 MOZ_ASSERT(!NS_IsMainThread());
79 NS_IMETHOD Run() override {
80 MOZ_ASSERT(NS_IsMainThread());
82 if (NS_FAILED(mRv)) {
83 mEnumerateFontsPromise->mPromise->MaybeReject(mRv);
84 } else {
85 mEnumerateFontsPromise->mPromise->MaybeResolve(mFontList);
88 mWorkerThread->Shutdown();
90 return NS_OK;
93 private:
94 nsresult mRv;
95 UniquePtr<EnumerateFontsPromise> mEnumerateFontsPromise;
96 nsTArray<nsString> mFontList;
97 nsCOMPtr<nsIThread> mWorkerThread;
100 class EnumerateFontsTask final : public Runnable {
101 public:
102 EnumerateFontsTask(nsAtom* aLangGroupAtom, const nsAutoCString& aGeneric,
103 UniquePtr<EnumerateFontsPromise> aEnumerateFontsPromise,
104 nsIEventTarget* aMainThreadTarget)
105 : Runnable("EnumerateFontsTask"),
106 mLangGroupAtom(aLangGroupAtom),
107 mGeneric(aGeneric),
108 mEnumerateFontsPromise(std::move(aEnumerateFontsPromise)),
109 mMainThreadTarget(aMainThreadTarget) {
110 MOZ_ASSERT(NS_IsMainThread());
113 NS_IMETHOD Run() override {
114 MOZ_ASSERT(!NS_IsMainThread());
116 nsTArray<nsString> fontList;
118 nsresult rv = gfxPlatform::GetPlatform()->GetFontList(mLangGroupAtom,
119 mGeneric, fontList);
120 nsCOMPtr<nsIRunnable> runnable = new EnumerateFontsResult(
121 rv, std::move(mEnumerateFontsPromise), std::move(fontList));
122 mMainThreadTarget->Dispatch(runnable.forget());
124 return NS_OK;
127 private:
128 RefPtr<nsAtom> mLangGroupAtom;
129 nsAutoCStringN<16> mGeneric;
130 UniquePtr<EnumerateFontsPromise> mEnumerateFontsPromise;
131 RefPtr<nsIEventTarget> mMainThreadTarget;
134 NS_IMETHODIMP
135 nsThebesFontEnumerator::EnumerateAllFontsAsync(
136 JSContext* aCx, JS::MutableHandle<JS::Value> aRval) {
137 return EnumerateFontsAsync(nullptr, nullptr, aCx, aRval);
140 NS_IMETHODIMP
141 nsThebesFontEnumerator::EnumerateFontsAsync(
142 const char* aLangGroup, const char* aGeneric, JSContext* aCx,
143 JS::MutableHandle<JS::Value> aRval) {
144 MOZ_ASSERT(NS_IsMainThread());
146 nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx);
147 NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
149 mozilla::ErrorResult errv;
150 RefPtr<mozilla::dom::Promise> promise =
151 mozilla::dom::Promise::Create(global, errv);
152 if (errv.Failed()) {
153 return errv.StealNSResult();
156 auto enumerateFontsPromise = MakeUnique<EnumerateFontsPromise>(promise);
158 nsCOMPtr<nsIThread> thread;
159 nsresult rv = NS_NewNamedThread("FontEnumThread", getter_AddRefs(thread));
160 NS_ENSURE_SUCCESS(rv, rv);
162 RefPtr<nsAtom> langGroupAtom;
163 if (aLangGroup) {
164 nsAutoCStringN<16> lowered;
165 lowered.Assign(aLangGroup);
166 ToLowerCase(lowered);
167 langGroupAtom = NS_Atomize(lowered);
170 nsAutoCString generic;
171 if (aGeneric) {
172 generic.Assign(aGeneric);
173 } else {
174 generic.SetIsVoid(true);
177 nsCOMPtr<nsIEventTarget> target = global->SerialEventTarget();
178 nsCOMPtr<nsIRunnable> runnable = new EnumerateFontsTask(
179 langGroupAtom, generic, std::move(enumerateFontsPromise), target);
180 thread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL);
182 if (!ToJSValue(aCx, promise, aRval)) {
183 return NS_ERROR_FAILURE;
186 return NS_OK;
189 NS_IMETHODIMP
190 nsThebesFontEnumerator::HaveFontFor(const char* aLangGroup, bool* aResult) {
191 NS_ENSURE_ARG_POINTER(aResult);
193 *aResult = true;
194 return NS_OK;
197 NS_IMETHODIMP
198 nsThebesFontEnumerator::GetDefaultFont(const char* aLangGroup,
199 const char* aGeneric,
200 char16_t** aResult) {
201 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aLangGroup) ||
202 NS_WARN_IF(!aGeneric)) {
203 return NS_ERROR_INVALID_ARG;
206 *aResult = nullptr;
207 nsAutoCString defaultFontName(gfxPlatform::GetPlatform()->GetDefaultFontName(
208 nsDependentCString(aLangGroup), nsDependentCString(aGeneric)));
209 if (!defaultFontName.IsEmpty()) {
210 *aResult = UTF8ToNewUnicode(defaultFontName);
212 return NS_OK;
215 NS_IMETHODIMP
216 nsThebesFontEnumerator::GetStandardFamilyName(const char16_t* aName,
217 char16_t** aResult) {
218 NS_ENSURE_ARG_POINTER(aResult);
219 NS_ENSURE_ARG_POINTER(aName);
221 nsAutoString name(aName);
222 if (name.IsEmpty()) {
223 *aResult = nullptr;
224 return NS_OK;
227 nsAutoCString family;
228 gfxPlatform::GetPlatform()->GetStandardFamilyName(
229 NS_ConvertUTF16toUTF8(aName), family);
230 if (family.IsEmpty()) {
231 *aResult = nullptr;
232 return NS_OK;
234 *aResult = UTF8ToNewUnicode(family);
235 return NS_OK;