virtual ~FontConfigTypeface()
 {
     const uint32_t id = uniqueID();
     if (IsRemoteFont(UniqueIdToFileFaceId(id))) {
         SkAutoMutexAcquire ac(global_remote_font_map_lock);
         AllocateGlobalRemoteFontsMapOnce();
         std::map<uint32_t, std::pair<uint8_t*, size_t> >::iterator iter
             = global_remote_fonts->find(id);
         if (iter != global_remote_fonts->end()) {
             sk_free(iter->second.first);  // remove the font on memory.
             global_remote_fonts->erase(iter);
         }
     }
 }
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
    SkFontDescriptor desc(face->style());

    std::string resolved_family_name;

    const unsigned filefaceid = UniqueIdToFileFaceId(face->uniqueID());
    if (GetFcImpl()->Match(&resolved_family_name, NULL,
            true /* filefaceid valid */, filefaceid, "", NULL, 0, NULL, NULL))
        desc.setFamilyName(resolved_family_name.c_str());
    else
        desc.setFamilyName("sans-serif");

    // would also like other names (see SkFontDescriptor.h)

    desc.serialize(stream);
    
    // by convention, we also write out the actual sfnt data, preceeded by
    // a packed-length. For now we skip that, so we just write the zero.
    stream->writePackedUInt(0);
}
// static
size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
                               int32_t* index) {
    const unsigned filefaceid = UniqueIdToFileFaceId(fontID);

    if (IsRemoteFont(filefaceid))
        return 0;

    if (index) {
        *index = filefaceid & 0xfu;
        // 1 is a bogus return value.
        // We had better change the signature of this function in Skia
        // to return bool to indicate success/failure and have another
        // out param for fileName length.
        if (!path)
          return 1;
    }

    if (path)
        SkASSERT(!"SkFontHost::GetFileName does not support the font path "
                  "retrieval.");

    return 0;
}
// static
SkStream* SkFontHost::OpenStream(uint32_t id)
{
    const unsigned filefaceid = UniqueIdToFileFaceId(id);

    if (IsRemoteFont(filefaceid)) {
      // remote font
      SkAutoMutexAcquire ac(global_remote_font_map_lock);
      AllocateGlobalRemoteFontsMapOnce();
      std::map<uint32_t, std::pair<uint8_t*, size_t> >::const_iterator iter
          = global_remote_fonts->find(id);
      if (iter == global_remote_fonts->end())
          return NULL;
      return SkNEW_ARGS(
          SkMemoryStream, (iter->second.first, iter->second.second));
    }

    // system font
    const int fd = GetFcImpl()->Open(filefaceid);
    if (fd < 0)
        return NULL;

    return SkNEW_ARGS(SkFileDescriptorStream, (fd));
}
// static
SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
                                       const char familyName[],
                                       SkTypeface::Style style)
{
    std::string resolved_family_name;

    if (familyFace) {
        // Given the fileid we can ask fontconfig for the familyname of the
        // font.
        const unsigned filefaceid = UniqueIdToFileFaceId(familyFace->uniqueID());
        if (!GetFcImpl()->Match(&resolved_family_name, NULL,
          true /* filefaceid valid */, filefaceid, "",
          NULL, 0, NULL, NULL)) {
            return NULL;
        }
    } else if (familyName) {
        resolved_family_name = familyName;
    }

    bool bold = style & SkTypeface::kBold;
    bool italic = style & SkTypeface::kItalic;
    unsigned filefaceid;
    if (!GetFcImpl()->Match(NULL, &filefaceid,
                            false, -1, /* no filefaceid */
                            resolved_family_name, NULL, 0,
                            &bold, &italic)) {
        return NULL;
    }
    const SkTypeface::Style resulting_style = static_cast<SkTypeface::Style>(
        (bold ? SkTypeface::kBold : 0) |
        (italic ? SkTypeface::kItalic : 0));

    const unsigned id = FileFaceIdAndStyleToUniqueId(filefaceid,
                                                     resulting_style);
    SkTypeface* typeface = SkNEW_ARGS(FontConfigTypeface, (resulting_style, id));
    return typeface;
}