sk_sp<SkTypeface> FontCache::createTypeface(
    const FontDescription& fontDescription,
    const FontFaceCreationParams& creationParams,
    CString& name) {
  AtomicString family = creationParams.family();

  if (family.isEmpty()) {
    name = getFallbackFontFamily(fontDescription).string().utf8();
  } else {
    name = family.utf8();
  }

  fonts::FontRequest request;
  request.family = name.data();
  request.weight = ToIntegerWeight(fontDescription.weight());
  request.width = static_cast<uint32_t>(fontDescription.stretch());
  request.slant = ToFontSlant(fontDescription.style());

  fonts::FontResponsePtr response;
  auto& font_provider = GetFontProvider();
  font_provider->GetFont(
      std::move(request),
      [&response](fonts::FontResponsePtr r) { response = std::move(r); });
  font_provider.WaitForResponse();

  FXL_DCHECK(response)
      << "Unable to contact the font provider. Did you run "
         "Flutter in an environment that has a font manager?\n"
         "See <https://fuchsia.googlesource.com/modular/+/master/README.md>.";

  if (!response)
    return nullptr;

  sk_sp<SkData> data = MakeSkDataFromBuffer(response->data.buffer);
  if (!data)
    return nullptr;

  return SkFontMgr::RefDefault()->makeFromData(std::move(data));
}
Exemple #2
0
std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(
    const FontDescription& fontDescription,
    const FontFaceCreationParams& creationParams,
    float fontSize) {
  ASSERT(creationParams.creationType() == CreateFontByFamily);

  CString name;
  sk_sp<SkTypeface> tf = createTypeface(fontDescription, creationParams, name);
  // Windows will always give us a valid pointer here, even if the face name
  // is non-existent. We have to double-check and see if the family name was
  // really used.
  if (!tf || !typefacesMatchesFamily(tf.get(), creationParams.family())) {
    AtomicString adjustedName;
    FontWeight variantWeight;
    FontStretch variantStretch;

    if (typefacesHasWeightSuffix(creationParams.family(), adjustedName,
                                 variantWeight)) {
      FontFaceCreationParams adjustedParams(adjustedName);
      FontDescription adjustedFontDescription = fontDescription;
      adjustedFontDescription.setWeight(variantWeight);
      tf = createTypeface(adjustedFontDescription, adjustedParams, name);
      if (!tf || !typefacesMatchesFamily(tf.get(), adjustedName))
        return nullptr;

    } else if (typefacesHasStretchSuffix(creationParams.family(), adjustedName,
                                         variantStretch)) {
      FontFaceCreationParams adjustedParams(adjustedName);
      FontDescription adjustedFontDescription = fontDescription;
      adjustedFontDescription.setStretch(variantStretch);
      tf = createTypeface(adjustedFontDescription, adjustedParams, name);
      if (!tf || !typefacesMatchesFamily(tf.get(), adjustedName))
        return nullptr;

    } else {
      return nullptr;
    }
  }

  std::unique_ptr<FontPlatformData> result =
      WTF::wrapUnique(new FontPlatformData(
          tf, name.data(), fontSize,
          (fontDescription.weight() >= FontWeight600 && !tf->isBold()) ||
              fontDescription.isSyntheticBold(),
          ((fontDescription.style() == FontStyleItalic ||
            fontDescription.style() == FontStyleOblique) &&
           !tf->isItalic()) ||
              fontDescription.isSyntheticItalic(),
          fontDescription.orientation()));

  struct FamilyMinSize {
    const wchar_t* family;
    unsigned minSize;
  };
  const static FamilyMinSize minAntiAliasSizeForFont[] = {
      {L"simsun", 11},
      {L"dotum", 12},
      {L"gulim", 12},
      {L"pmingliu", 11},
      {L"pmingliu-extb", 11}};
  size_t numFonts = WTF_ARRAY_LENGTH(minAntiAliasSizeForFont);
  for (size_t i = 0; i < numFonts; i++) {
    FamilyMinSize entry = minAntiAliasSizeForFont[i];
    if (typefacesMatchesFamily(tf.get(), entry.family)) {
      result->setMinSizeForAntiAlias(entry.minSize);
      break;
    }
  }

  // List of fonts that look bad with subpixel text rendering at smaller font
  // sizes. This includes all fonts in the Microsoft Core fonts for the Web
  // collection.
  const static wchar_t* noSubpixelForSmallSizeFont[] = {
      L"andale mono", L"arial",           L"comic sans",   L"courier new",
      L"dotum",       L"georgia",         L"impact",       L"lucida console",
      L"tahoma",      L"times new roman", L"trebuchet ms", L"verdana",
      L"webdings"};
  const static float minSizeForSubpixelForFont = 16.0f;
  numFonts = WTF_ARRAY_LENGTH(noSubpixelForSmallSizeFont);
  for (size_t i = 0; i < numFonts; i++) {
    const wchar_t* family = noSubpixelForSmallSizeFont[i];
    if (typefacesMatchesFamily(tf.get(), family)) {
      result->setMinSizeForSubpixel(minSizeForSubpixelForFont);
      break;
    }
  }

  return result;
}