tor-browser

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

nsThebesFontEnumerator.cpp (7237B)


      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/. */
      5 
      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
     20 
     21 using mozilla::MakeUnique;
     22 using mozilla::Runnable;
     23 using mozilla::UniquePtr;
     24 
     25 NS_IMPL_ISUPPORTS(nsThebesFontEnumerator, nsIFontEnumerator)
     26 
     27 nsThebesFontEnumerator::nsThebesFontEnumerator() = default;
     28 
     29 NS_IMETHODIMP
     30 nsThebesFontEnumerator::EnumerateAllFonts(nsTArray<nsString>& aResult) {
     31  return EnumerateFonts(nullptr, nullptr, aResult);
     32 }
     33 
     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);
     43 
     44  RefPtr<nsAtom> langGroupAtom;
     45  if (aLangGroup) {
     46    nsAutoCString lowered;
     47    lowered.Assign(aLangGroup);
     48    ToLowerCase(lowered);
     49    langGroupAtom = NS_Atomize(lowered);
     50  }
     51 
     52  return gfxPlatform::GetPlatform()->GetFontList(langGroupAtom, generic,
     53                                                 aResult);
     54 }
     55 
     56 struct EnumerateFontsPromise final {
     57  explicit EnumerateFontsPromise(mozilla::dom::Promise* aPromise)
     58      : mPromise(aPromise) {
     59    MOZ_ASSERT(aPromise);
     60    MOZ_ASSERT(NS_IsMainThread());
     61  }
     62 
     63  RefPtr<mozilla::dom::Promise> mPromise;
     64 };
     65 
     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());
     77  }
     78 
     79  NS_IMETHOD Run() override {
     80    MOZ_ASSERT(NS_IsMainThread());
     81 
     82    if (NS_FAILED(mRv)) {
     83      mEnumerateFontsPromise->mPromise->MaybeReject(mRv);
     84    } else {
     85      mEnumerateFontsPromise->mPromise->MaybeResolve(mFontList);
     86    }
     87 
     88    mWorkerThread->Shutdown();
     89 
     90    return NS_OK;
     91  }
     92 
     93 private:
     94  nsresult mRv;
     95  UniquePtr<EnumerateFontsPromise> mEnumerateFontsPromise;
     96  nsTArray<nsString> mFontList;
     97  nsCOMPtr<nsIThread> mWorkerThread;
     98 };
     99 
    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());
    111  }
    112 
    113  NS_IMETHOD Run() override {
    114    MOZ_ASSERT(!NS_IsMainThread());
    115 
    116    nsTArray<nsString> fontList;
    117 
    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());
    123 
    124    return NS_OK;
    125  }
    126 
    127 private:
    128  RefPtr<nsAtom> mLangGroupAtom;
    129  nsAutoCStringN<16> mGeneric;
    130  UniquePtr<EnumerateFontsPromise> mEnumerateFontsPromise;
    131  RefPtr<nsIEventTarget> mMainThreadTarget;
    132 };
    133 
    134 NS_IMETHODIMP
    135 nsThebesFontEnumerator::EnumerateAllFontsAsync(
    136    JSContext* aCx, JS::MutableHandle<JS::Value> aRval) {
    137  return EnumerateFontsAsync(nullptr, nullptr, aCx, aRval);
    138 }
    139 
    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());
    145 
    146  nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx);
    147  NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
    148 
    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();
    154  }
    155 
    156  auto enumerateFontsPromise = MakeUnique<EnumerateFontsPromise>(promise);
    157 
    158  nsCOMPtr<nsIThread> thread;
    159  nsresult rv = NS_NewNamedThread("FontEnumThread", getter_AddRefs(thread));
    160  NS_ENSURE_SUCCESS(rv, rv);
    161 
    162  RefPtr<nsAtom> langGroupAtom;
    163  if (aLangGroup) {
    164    nsAutoCStringN<16> lowered;
    165    lowered.Assign(aLangGroup);
    166    ToLowerCase(lowered);
    167    langGroupAtom = NS_Atomize(lowered);
    168  }
    169 
    170  nsAutoCString generic;
    171  if (aGeneric) {
    172    generic.Assign(aGeneric);
    173  } else {
    174    generic.SetIsVoid(true);
    175  }
    176 
    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);
    181 
    182  if (!ToJSValue(aCx, promise, aRval)) {
    183    return NS_ERROR_FAILURE;
    184  }
    185 
    186  return NS_OK;
    187 }
    188 
    189 NS_IMETHODIMP
    190 nsThebesFontEnumerator::HaveFontFor(const char* aLangGroup, bool* aResult) {
    191  NS_ENSURE_ARG_POINTER(aResult);
    192 
    193  *aResult = true;
    194  return NS_OK;
    195 }
    196 
    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;
    204  }
    205 
    206  *aResult = nullptr;
    207  nsAutoCString defaultFontName(gfxPlatform::GetPlatform()->GetDefaultFontName(
    208      nsDependentCString(aLangGroup), nsDependentCString(aGeneric)));
    209  if (!defaultFontName.IsEmpty()) {
    210    *aResult = UTF8ToNewUnicode(defaultFontName);
    211  }
    212  return NS_OK;
    213 }
    214 
    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);
    220 
    221  nsAutoString name(aName);
    222  if (name.IsEmpty()) {
    223    *aResult = nullptr;
    224    return NS_OK;
    225  }
    226 
    227  nsAutoCString family;
    228  gfxPlatform::GetPlatform()->GetStandardFamilyName(
    229      NS_ConvertUTF16toUTF8(aName), family);
    230  if (family.IsEmpty()) {
    231    *aResult = nullptr;
    232    return NS_OK;
    233  }
    234  *aResult = UTF8ToNewUnicode(family);
    235  return NS_OK;
    236 }