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/public.bzl b/public.bzl
index b360a11..60ce79d 100644
--- a/public.bzl
+++ b/public.bzl
@@ -300,6 +300,7 @@
         "src/ports/SkFontMgr_empty_factory.cpp",
         "src/ports/SkFontMgr_fontconfig.cpp",
         "src/ports/SkFontMgr_fontconfig_factory.cpp",
+        "src/ports/SkFontMgr_fuchsia.cpp",
         "src/ports/SkImageGenerator_none.cpp",
         "src/ports/SkTLS_none.cpp",
     ],
@@ -327,6 +328,7 @@
         "src/ports/SkFontMgr_custom_embedded_factory.cpp",
         "src/ports/SkFontMgr_custom_empty_factory.cpp",
         "src/ports/SkFontMgr_empty_factory.cpp",
+        "src/ports/SkFontMgr_fuchsia.cpp",
         "src/ports/SkImageGenerator_none.cpp",
         "src/ports/SkTLS_none.cpp",
     ],
@@ -358,6 +360,7 @@
         "src/ports/SkFontMgr_custom_embedded_factory.cpp",
         "src/ports/SkFontMgr_custom_empty_factory.cpp",
         "src/ports/SkFontMgr_empty_factory.cpp",
+        "src/ports/SkFontMgr_fuchsia.cpp",
         "src/ports/SkImageGenerator_none.cpp",
         "src/ports/SkTLS_none.cpp",
     ],
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));
+}
