blob: 132f146e3323ec1c3b28fecdaa8f42560d4489be [file] [log] [blame]
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "build/build_config.h"
#include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/fonts/font_platform_data.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
#include "ui/gfx/font_fallback_linux.h"
namespace blink {
static AtomicString& MutableSystemFontFamily() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(AtomicString, system_font_family, ());
return system_font_family;
}
// static
const AtomicString& FontCache::SystemFontFamily() {
return MutableSystemFontFamily();
}
// static
void FontCache::SetSystemFontFamily(const AtomicString& family_name) {
DCHECK(!family_name.IsEmpty());
MutableSystemFontFamily() = family_name;
}
bool FontCache::GetFontForCharacter(UChar32 c,
const char* preferred_locale,
gfx::FallbackFontData* fallback_font) {
if (Platform::Current()->GetSandboxSupport()) {
return Platform::Current()
->GetSandboxSupport()
->GetFallbackFontForCharacter(c, preferred_locale, fallback_font);
} else {
std::string locale = preferred_locale ? preferred_locale : std::string();
return gfx::GetFallbackFontForChar(c, locale, fallback_font);
}
}
scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
const FontDescription& font_description,
UChar32 c,
const SimpleFontData*,
FontFallbackPriority fallback_priority) {
// The m_fontManager is set only if it was provided by the embedder with
// WebFontRendering::setSkiaFontManager. This is used to emulate android fonts
// on linux so we always request the family from the font manager and if none
// is found, we return the LastResort fallback font and avoid using
// FontCache::GetFontForCharacter which would use sandbox support to query the
// underlying system for the font family.
if (font_manager_) {
AtomicString family_name = GetFamilyNameForCharacter(
font_manager_.get(), c, font_description, fallback_priority);
if (family_name.IsEmpty())
return GetLastResortFallbackFont(font_description, kDoNotRetain);
return FontDataFromFontPlatformData(
GetFontPlatformData(font_description,
FontFaceCreationParams(family_name)),
kDoNotRetain);
}
if (fallback_priority == FontFallbackPriority::kEmojiEmoji) {
// FIXME crbug.com/591346: We're overriding the fallback character here
// with the FAMILY emoji in the hope to find a suitable emoji font.
// This should be improved by supporting fallback for character
// sequences like DIGIT ONE + COMBINING keycap etc.
c = kFamilyCharacter;
}
// First try the specified font with standard style & weight.
if (fallback_priority != FontFallbackPriority::kEmojiEmoji &&
(font_description.Style() == ItalicSlopeValue() ||
font_description.Weight() >= BoldThreshold())) {
scoped_refptr<SimpleFontData> font_data =
FallbackOnStandardFontStyle(font_description, c);
if (font_data)
return font_data;
}
gfx::FallbackFontData fallback_font;
if (!FontCache::GetFontForCharacter(
c,
fallback_priority == FontFallbackPriority::kEmojiEmoji
? kColorEmojiLocale
: font_description.LocaleOrDefault().Ascii().c_str(),
&fallback_font))
return nullptr;
FontFaceCreationParams creation_params;
creation_params = FontFaceCreationParams(
fallback_font.filepath.value(), fallback_font.fontconfig_interface_id,
fallback_font.ttc_index);
// Changes weight and/or italic of given FontDescription depends on
// the result of fontconfig so that keeping the correct font mapping
// of the given character. See http://crbug.com/32109 for details.
bool should_set_synthetic_bold = false;
bool should_set_synthetic_italic = false;
FontDescription description(font_description);
if (fallback_font.is_bold && description.Weight() < BoldThreshold())
description.SetWeight(BoldWeightValue());
if (!fallback_font.is_bold && description.Weight() >= BoldThreshold()) {
should_set_synthetic_bold = true;
description.SetWeight(NormalWeightValue());
}
if (fallback_font.is_italic && description.Style() == NormalSlopeValue())
description.SetStyle(ItalicSlopeValue());
if (!fallback_font.is_italic && (description.Style() == ItalicSlopeValue())) {
should_set_synthetic_italic = true;
description.SetStyle(NormalSlopeValue());
}
FontPlatformData* substitute_platform_data =
GetFontPlatformData(description, creation_params);
if (!substitute_platform_data)
return nullptr;
std::unique_ptr<FontPlatformData> platform_data(
new FontPlatformData(*substitute_platform_data));
platform_data->SetSyntheticBold(should_set_synthetic_bold);
platform_data->SetSyntheticItalic(should_set_synthetic_italic);
return FontDataFromFontPlatformData(platform_data.get(), kDoNotRetain);
}
} // namespace blink