// 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;
}
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
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));
}