diff --git a/BUILD.gn b/BUILD.gn
index b4cf3d3..0fade34 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -73,6 +73,7 @@
                                skia_use_freetype && !skia_use_fontconfig
   skia_enable_fontmgr_custom_empty = is_fuchsia && skia_use_freetype
   skia_enable_fontmgr_android = skia_use_expat && skia_use_freetype
+  skia_enable_fontmgr_fuchsia = is_fuchsia
 
   if (is_android) {
     skia_use_vulkan = defined(ndk_api) && ndk_api >= 24
@@ -411,6 +412,18 @@
   ]
 }
 
+optional("fontmgr_fuchsia") {
+  enabled = skia_enable_fontmgr_fuchsia
+
+  deps = [
+    "//garnet/public/fidl/fuchsia.fonts",
+  ]
+  sources = [
+    "src/ports/SkFontMgr_fuchsia.cpp",
+    "src/ports/SkFontMgr_fuchsia.h",
+  ]
+}
+
 optional("fontmgr_empty") {
   enabled = skia_enable_fontmgr_empty
   sources = [
@@ -854,6 +867,7 @@
     ":fontmgr_custom_empty",
     ":fontmgr_empty",
     ":fontmgr_fontconfig",
+    ":fontmgr_fuchsia",
     ":heif",
     ":hsw",
     ":jpeg",
@@ -983,9 +997,7 @@
   }
 
   if (skia_use_fonthost_mac) {
-    sources += [
-      "src/ports/SkFontHost_mac.cpp",
-    ]
+    sources += [ "src/ports/SkFontHost_mac.cpp" ]
   }
 
   if (is_mac) {
diff --git a/include/ports/SkFontMgr_fuchsia.h b/include/ports/SkFontMgr_fuchsia.h
new file mode 100644
index 0000000..4bcff82
--- /dev/null
+++ b/include/ports/SkFontMgr_fuchsia.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontMgr_fuchsia_DEFINED
+#define SkFontMgr_fuchsia_DEFINED
+
+#include <fuchsia/fonts/cpp/fidl.h>
+
+#include "SkRefCnt.h"
+
+class SkFontMgr;
+
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Fuchsia(fuchsia::fonts::ProviderSyncPtr provider);
+
+#endif  // SkFontMgr_fuchsia_DEFINED
diff --git a/src/ports/SkFontMgr_fuchsia.cpp b/src/ports/SkFontMgr_fuchsia.cpp
new file mode 100644
index 0000000..81d621a
--- /dev/null
+++ b/src/ports/SkFontMgr_fuchsia.cpp
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkFontMgr_fuchsia.h"
+
+#include <fuchsia/fonts/cpp/fidl.h>
+#include <lib/zx/vmar.h>
+#include <strings.h>
+#include <memory>
+#include <unordered_map>
+
+#include "third_party/skia/src/core/SkFontDescriptor.h"
+#include "third_party/skia/src/ports/SkFontMgr_custom.h"
+
+#include "SkFontMgr.h"
+#include "SkStream.h"
+#include "SkTypeface.h"
+#include "SkTypefaceCache.h"
+
+void UnmapMemory(const void* buffer, uint64_t size) {
+    static_assert(sizeof(void*) == sizeof(uint64_t), "pointers aren't 64-bit");
+    zx::vmar::root_self()->unmap(reinterpret_cast<uintptr_t>(buffer), size);
+}
+
+struct ReleaseSkDataContext {
+    uint64_t fBufferSize;
+    std::function<void()> releaseProc;
+
+    ReleaseSkDataContext(uint64_t bufferSize, const std::function<void()>& releaseProc)
+            : fBufferSize(bufferSize), releaseProc(releaseProc) {}
+};
+
+void ReleaseSkData(const void* buffer, void* context) {
+    auto releaseSkDataContext = reinterpret_cast<ReleaseSkDataContext*>(context);
+    SkASSERT(releaseSkDataContext);
+    UnmapMemory(buffer, releaseSkDataContext->fBufferSize);
+    releaseSkDataContext->releaseProc();
+    delete releaseSkDataContext;
+}
+
+sk_sp<SkData> MakeSkDataFromBuffer(const fuchsia::mem::Buffer& data,
+                                   std::function<void()> release_proc) {
+    uint64_t size = data.size;
+    uintptr_t buffer = 0;
+    zx_status_t status = zx::vmar::root_self()->map(0, data.vmo, 0, size, ZX_VM_PERM_READ, &buffer);
+    if (status != ZX_OK) return nullptr;
+    auto context = new ReleaseSkDataContext(size, release_proc);
+    return SkData::MakeWithProc(reinterpret_cast<void*>(buffer), size, ReleaseSkData, context);
+}
+
+fuchsia::fonts::Slant SkToFuchsiaSlant(SkFontStyle::Slant slant) {
+    switch (slant) {
+        case SkFontStyle::kOblique_Slant:
+            return fuchsia::fonts::Slant::OBLIQUE;
+        case SkFontStyle::kItalic_Slant:
+            return fuchsia::fonts::Slant::ITALIC;
+        case SkFontStyle::kUpright_Slant:
+        default:
+            return fuchsia::fonts::Slant::UPRIGHT;
+    }
+}
+
+SkFontStyle::Slant FuchsiaToSkSlant(fuchsia::fonts::Slant slant) {
+    switch (slant) {
+        case fuchsia::fonts::Slant::OBLIQUE:
+            return SkFontStyle::kOblique_Slant;
+        case fuchsia::fonts::Slant::ITALIC:
+            return SkFontStyle::kItalic_Slant;
+        case fuchsia::fonts::Slant::UPRIGHT:
+        default:
+            return SkFontStyle::kUpright_Slant;
+    }
+}
+
+constexpr struct {
+    const char* fName;
+    fuchsia::fonts::FallbackGroup fFallbackGroup;
+} kFallbackGroupsByName[] = {
+        {"serif", fuchsia::fonts::FallbackGroup::SERIF},
+        {"sans", fuchsia::fonts::FallbackGroup::SANS_SERIF},
+        {"sans-serif", fuchsia::fonts::FallbackGroup::SANS_SERIF},
+        {"mono", fuchsia::fonts::FallbackGroup::MONOSPACE},
+        {"monospace", fuchsia::fonts::FallbackGroup::MONOSPACE},
+        {"cursive", fuchsia::fonts::FallbackGroup::CURSIVE},
+        {"fantasy", fuchsia::fonts::FallbackGroup::FANTASY},
+};
+
+fuchsia::fonts::FallbackGroup GetFallbackGroupByName(const char* name) {
+    if (!name) return fuchsia::fonts::FallbackGroup::NONE;
+    for (auto& group : kFallbackGroupsByName) {
+        if (strcasecmp(group.fName, name) == 0) {
+            return group.fFallbackGroup;
+        }
+    }
+    return fuchsia::fonts::FallbackGroup::NONE;
+}
+
+struct TypefaceId {
+    uint32_t bufferId;
+    uint32_t ttcIndex;
+
+    bool operator==(TypefaceId& other) {
+        return std::tie(bufferId, ttcIndex) == std::tie(other.bufferId, other.ttcIndex);
+    }
+}
+
+constexpr kNullTypefaceId = {0xFFFFFFFF, 0xFFFFFFFF};
+
+class SkTypeface_Fuchsia : public SkTypeface_Stream {
+public:
+    SkTypeface_Fuchsia(std::unique_ptr<SkFontData> fontData, const SkFontStyle& style,
+                       bool isFixedPitch, const SkString familyName, TypefaceId id)
+            : SkTypeface_Stream(std::move(fontData), style, isFixedPitch,
+                                /*sys_font=*/true, familyName)
+            , fId(id) {}
+
+    TypefaceId id() { return fId; }
+
+private:
+    TypefaceId fId;
+};
+
+sk_sp<SkTypeface> CreateTypefaceFromSkStream(std::unique_ptr<SkStreamAsset> stream,
+                                             const SkFontArguments& args, TypefaceId id) {
+    using Scanner = SkTypeface_FreeType::Scanner;
+    Scanner scanner;
+    bool isFixedPitch;
+    SkFontStyle style;
+    SkString name;
+    Scanner::AxisDefinitions axisDefinitions;
+    if (!scanner.scanFont(stream.get(), args.getCollectionIndex(), &name, &style, &isFixedPitch,
+                          &axisDefinitions)) {
+        return nullptr;
+    }
+
+    const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
+    SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
+    Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
+
+    auto fontData = std::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
+                                                 axisValues.get(), axisDefinitions.count());
+    return sk_make_sp<SkTypeface_Fuchsia>(std::move(fontData), style, isFixedPitch, name, id);
+}
+
+sk_sp<SkTypeface> CreateTypefaceFromSkData(sk_sp<SkData> data, TypefaceId id) {
+    return CreateTypefaceFromSkStream(std::make_unique<SkMemoryStream>(std::move(data)),
+                                      SkFontArguments().setCollectionIndex(id.ttcIndex), id);
+}
+
+class SkFontMgr_Fuchsia final : public SkFontMgr {
+public:
+    SkFontMgr_Fuchsia(fuchsia::fonts::ProviderSyncPtr provider);
+    ~SkFontMgr_Fuchsia() override;
+
+protected:
+    // SkFontMgr overrides.
+    int onCountFamilies() const override;
+    void onGetFamilyName(int index, SkString* familyName) const override;
+    SkFontStyleSet* onMatchFamily(const char familyName[]) const override;
+    SkFontStyleSet* onCreateStyleSet(int index) const override;
+    SkTypeface* onMatchFamilyStyle(const char familyName[], const SkFontStyle&) const override;
+    SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+                                            const char* bcp47[], int bcp47Count,
+                                            SkUnichar character) const override;
+    SkTypeface* onMatchFaceStyle(const SkTypeface*, const SkFontStyle&) const override;
+    sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const override;
+    sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
+                                            int ttcIndex) const override;
+    sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
+                                           const SkFontArguments&) const override;
+    sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override;
+    sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle) const override;
+
+private:
+    friend class SkFontStyleSet_Fuchsia;
+
+    sk_sp<SkTypeface> FetchTypeface(const char familyName[], const SkFontStyle& style,
+                                    const char* bcp47[], int bcp47Count, SkUnichar character,
+                                    bool allow_fallback, bool exact_style_match) const;
+
+    sk_sp<SkData> GetOrCreateSkData(int bufferId, const fuchsia::mem::Buffer& buffer) const;
+    void OnSkDataDeleted(int bufferId) const;
+
+    sk_sp<SkTypeface> GetOrCreateTypeface(TypefaceId id, const fuchsia::mem::Buffer& buffer) const;
+
+    mutable fuchsia::fonts::ProviderSyncPtr fFontProvider;
+
+    mutable SkMutex fCacheMutex;
+
+    // Must be accessed only with fCacheMutex acquired.
+    mutable std::unordered_map<int, SkData*> fBufferCache;
+    mutable SkTypefaceCache fTypefaceCache;
+};
+
+class SkFontStyleSet_Fuchsia : public SkFontStyleSet {
+public:
+    SkFontStyleSet_Fuchsia(sk_sp<SkFontMgr_Fuchsia> font_manager, std::string familyName,
+                 std::vector<SkFontStyle> styles)
+            : fFontManager(font_manager), fFamilyName(familyName), fStyles(styles) {}
+
+    ~SkFontStyleSet_Fuchsia() override = default;
+
+    int count() override { return fStyles.size(); }
+
+    void getStyle(int index, SkFontStyle* style, SkString* styleName) override {
+        SkASSERT(index >= 0 && index < static_cast<int>(fStyles.size()));
+        if (style) *style = fStyles[index];
+
+        // We don't have style names. Return an empty name.
+        if (styleName) styleName->reset();
+    }
+
+    SkTypeface* createTypeface(int index) override {
+        SkASSERT(index >= 0 && index < static_cast<int>(fStyles.size()));
+
+        if (fTypefaces.empty()) fTypefaces.resize(fStyles.size());
+
+        if (!fTypefaces[index]) {
+            fTypefaces[index] = fFontManager->FetchTypeface(
+                    fFamilyName.c_str(), fStyles[index], /*bcp47=*/nullptr,
+                    /*bcp47Count=*/0, /*character=*/0,
+                    /*allow_fallback=*/false, /*exact_style_match=*/true);
+        }
+
+        return SkSafeRef(fTypefaces[index].get());
+    }
+
+    SkTypeface* matchStyle(const SkFontStyle& pattern) override { return matchStyleCSS3(pattern); }
+
+private:
+    sk_sp<SkFontMgr_Fuchsia> fFontManager;
+    std::string fFamilyName;
+    std::vector<SkFontStyle> fStyles;
+    std::vector<sk_sp<SkTypeface>> fTypefaces;
+};
+
+SkFontMgr_Fuchsia::SkFontMgr_Fuchsia(fuchsia::fonts::ProviderSyncPtr provider)
+        : fFontProvider(std::move(provider)) {}
+
+SkFontMgr_Fuchsia::~SkFontMgr_Fuchsia() = default;
+
+int SkFontMgr_Fuchsia::onCountFamilies() const {
+    // Family enumeration is not supported.
+    return 0;
+}
+
+void SkFontMgr_Fuchsia::onGetFamilyName(int index, SkString* familyName) const {
+    // Family enumeration is not supported.
+    familyName->reset();
+}
+
+SkFontStyleSet* SkFontMgr_Fuchsia::onCreateStyleSet(int index) const {
+    // Family enumeration is not supported.
+    return nullptr;
+}
+
+SkFontStyleSet* SkFontMgr_Fuchsia::onMatchFamily(const char familyName[]) const {
+    fuchsia::fonts::FamilyInfoPtr familyInfo;
+    int result = fFontProvider->GetFamilyInfo(familyName, &familyInfo);
+    if (result != ZX_OK || !familyInfo) return nullptr;
+
+    std::vector<SkFontStyle> styles;
+    for (auto& style : *(familyInfo->styles)) {
+        styles.push_back(SkFontStyle(style.weight, style.width, FuchsiaToSkSlant(style.slant)));
+    }
+
+    return new SkFontStyleSet_Fuchsia(sk_ref_sp(this), familyInfo->name, std::move(styles));
+}
+
+SkTypeface* SkFontMgr_Fuchsia::onMatchFamilyStyle(const char familyName[],
+                                                  const SkFontStyle& style) const {
+    sk_sp<SkTypeface> typeface =
+            FetchTypeface(familyName, style, /*bcp47=*/nullptr,
+                          /*bcp47Count=*/0, /*character=*/0,
+                          /*allow_fallback=*/false, /*exact_style_match=*/false);
+    return typeface.release();
+}
+
+SkTypeface* SkFontMgr_Fuchsia::onMatchFamilyStyleCharacter(const char familyName[],
+                                                           const SkFontStyle& style,
+                                                           const char* bcp47[], int bcp47Count,
+                                                           SkUnichar character) const {
+    sk_sp<SkTypeface> typeface =
+            FetchTypeface(familyName, style, bcp47, bcp47Count, character, /*allow_fallback=*/true,
+                          /*exact_style_match=*/false);
+    return typeface.release();
+}
+
+SkTypeface* SkFontMgr_Fuchsia::onMatchFaceStyle(const SkTypeface*, const SkFontStyle&) const {
+    return nullptr;
+}
+
+sk_sp<SkTypeface> SkFontMgr_Fuchsia::onMakeFromData(sk_sp<SkData>, int ttcIndex) const {
+    SkASSERT(false);
+    return nullptr;
+}
+
+sk_sp<SkTypeface> SkFontMgr_Fuchsia::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> asset,
+                                                           int ttcIndex) const {
+    return makeFromStream(std::move(asset), SkFontArguments().setCollectionIndex(ttcIndex));
+}
+
+sk_sp<SkTypeface> SkFontMgr_Fuchsia::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> asset,
+                                                          const SkFontArguments& args) const {
+    return CreateTypefaceFromSkStream(std::move(asset), args, kNullTypefaceId);
+}
+
+sk_sp<SkTypeface> SkFontMgr_Fuchsia::onMakeFromFile(const char path[], int ttcIndex) const {
+    return makeFromStream(std::make_unique<SkFILEStream>(path), ttcIndex);
+}
+
+sk_sp<SkTypeface> SkFontMgr_Fuchsia::onLegacyMakeTypeface(const char familyName[],
+                                                          SkFontStyle style) const {
+    return sk_sp<SkTypeface>(matchFamilyStyle(familyName, style));
+}
+
+sk_sp<SkTypeface> SkFontMgr_Fuchsia::FetchTypeface(const char familyName[],
+                                                   const SkFontStyle& style, const char* bcp47[],
+                                                   int bcp47Count, SkUnichar character,
+                                                   bool allow_fallback,
+                                                   bool exact_style_match) const {
+    fuchsia::fonts::Request request;
+    request.weight = style.weight();
+    request.width = style.width();
+    request.slant = SkToFuchsiaSlant(style.slant());
+    request.language.reset(std::vector<fidl::StringPtr>(bcp47, bcp47 + bcp47Count));
+    request.character = character;
+    request.fallback_group = GetFallbackGroupByName(familyName);
+
+    // If family name is not specified or it is a generic fallback group name (e.g. "serif") then
+    // enable fallback, otherwise pass the family name as is.
+    if (!familyName || *familyName == '\0' ||
+        request.fallback_group != fuchsia::fonts::FallbackGroup::NONE) {
+        request.family = "";
+        allow_fallback = true;
+    } else {
+        request.family = familyName;
+    }
+
+    request.flags = 0;
+    if (!allow_fallback) request.flags |= fuchsia::fonts::REQUEST_FLAG_NO_FALLBACK;
+    if (exact_style_match) request.flags |= fuchsia::fonts::REQUEST_FLAG_EXACT_MATCH;
+
+    fuchsia::fonts::ResponsePtr response;
+    int result = fFontProvider->GetFont(std::move(request), &response);
+    if (result != ZX_OK) return nullptr;
+
+    // The service may return null response if there is no font matching the request.
+    if (!response) return nullptr;
+
+    return GetOrCreateTypeface(TypefaceId{response->buffer_id, response->font_index},
+                               response->buffer);
+}
+
+sk_sp<SkData> SkFontMgr_Fuchsia::GetOrCreateSkData(int bufferId,
+                                                   const fuchsia::mem::Buffer& buffer) const {
+    fCacheMutex.assertHeld();
+
+    auto iter = fBufferCache.find(bufferId);
+    if (iter != fBufferCache.end()) {
+        return sk_ref_sp(iter->second);
+    }
+    auto font_mgr = sk_ref_sp(this);
+    auto data = MakeSkDataFromBuffer(buffer,
+                                     [font_mgr, bufferId]() { font_mgr->OnSkDataDeleted(bufferId); });
+    if (!data) {
+        return nullptr;
+    }
+    fBufferCache[bufferId] = data.get();
+    return data;
+}
+
+void SkFontMgr_Fuchsia::OnSkDataDeleted(int bufferId) const {
+    SK_UNUSED bool wasFound = fBufferCache.erase(bufferId) != 0;
+    SkASSERT(wasFound);
+}
+
+static bool FindByTypefaceId(SkTypeface* cachedTypeface, void* ctx) {
+    SkTypeface_Fuchsia* cachedFuchsiaTypeface = static_cast<SkTypeface_Fuchsia*>(cachedTypeface);
+    TypefaceId* id = static_cast<TypefaceId*>(ctx);
+
+    return cachedFuchsiaTypeface->id() == *id;
+}
+
+sk_sp<SkTypeface> SkFontMgr_Fuchsia::GetOrCreateTypeface(TypefaceId id,
+                                                         const fuchsia::mem::Buffer& buffer) const {
+    SkAutoMutexAcquire mutexLock(fCacheMutex);
+
+    SkTypeface* cached = fTypefaceCache.findByProcAndRef(FindByTypefaceId, &id);
+    if (cached) return sk_sp<SkTypeface>(cached);
+
+    sk_sp<SkData> data = GetOrCreateSkData(id.bufferId, buffer);
+    if (!data) return nullptr;
+
+    auto result = CreateTypefaceFromSkData(std::move(data), id);
+    fTypefaceCache.add(result.get());
+    return result;
+}
+
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Fuchsia(fuchsia::fonts::ProviderSyncPtr provider) {
+    return sk_make_sp<SkFontMgr_Fuchsia>(std::move(provider));
+}
