Example #1
0
uint qHash(const FontDescription& key)
{
    uint value = CaseFoldingHash::hash(key.family().family());
    value ^= key.computedPixelSize();
    value ^= static_cast<int>(key.weight());
    return value;
}
Example #2
0
void FontBuilder::setFontFamilyInherit(const FontDescription& parentFontDescription)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setGenericFamily(parentFontDescription.genericFamily());
    scope.fontDescription().setFamily(parentFontDescription.family());
}
Example #3
0
FallbackListCompositeKey FontFallbackList::compositeKey(const FontDescription& fontDescription) const
{
    FallbackListCompositeKey key(fontDescription);
    const FontFamily* currentFamily = &fontDescription.family();
    while (currentFamily) {
        if (currentFamily->family().length()) {
            FontFaceCreationParams params(adjustFamilyNameToAvoidUnsupportedFonts(currentFamily->family()));
            RefPtr<FontData> result;
            if (m_fontSelector)
                result = m_fontSelector->getFontData(fontDescription, currentFamily->family());
            if (!result) {
                if (FontPlatformData* platformData = FontCache::fontCache()->getFontPlatformData(fontDescription, params))
                    result = FontCache::fontCache()->fontDataFromFontPlatformData(platformData);
            }

            // Include loading state and version when constructing key, that way if called when a font is loading
            // and then again once it has been loaded or updated different keys are produced.
            if (result) {
                FontCacheKey cacheKey = fontDescription.cacheKey(params, FontTraits(0),
                    result->isLoading() || result->isLoadingFallback(),
                    m_fontSelector ? m_fontSelector->version() : 0);
                key.add(cacheKey);
            }
        }
        currentFamily = currentFamily->next();
    }

    return key;
}
Example #4
0
SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
    FontDescription desc = FontDescription(fontDescription);
    desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
    FontPlatformData platformData(desc, desc.family().family());
    return new SimpleFontData(platformData, isCustomFont(), false);
}
PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
    FontDescription desc = FontDescription(fontDescription);
    desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
    FontPlatformData fontPlatformData(desc, desc.family().family());
    return adoptPtr(new SimpleFontData(fontPlatformData, isCustomFont(), false));
}
Example #6
0
SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
    if (!m_smallCapsFontData) {
        FontDescription desc = FontDescription(fontDescription);
        desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
        const FontPlatformData* fontPlatformData = new FontPlatformData(desc, desc.family().family());
        m_smallCapsFontData = new SimpleFontData(*fontPlatformData);
    }
    return m_smallCapsFontData;
}
WebFontDescription::WebFontDescription(const FontDescription& desc)
{
    family = desc.family().family();
    genericFamily = static_cast<GenericFamily>(desc.genericFamily());
    size = desc.specifiedSize();
    italic = desc.style() == FontStyleItalic;
    smallCaps = desc.variant() == FontVariantSmallCaps;
    weight = static_cast<Weight>(desc.weight());
    smoothing = static_cast<Smoothing>(desc.fontSmoothing());
    letterSpacing = desc.letterSpacing();
    wordSpacing = desc.wordSpacing();
}
FontTranscoder::ConverterType FontTranscoder::converterType(const FontDescription& fontDescription, const TextEncoding* encoding) const
{
    const AtomicString& fontFamily = fontDescription.family().family().string();
    if (!fontFamily.isNull()) {
        HashMap<AtomicString, ConverterType>::const_iterator found = m_converterTypes.find(fontFamily);
        if (found != m_converterTypes.end())
            return found->second;
    }

    // IE's default fonts for Japanese encodings change backslashes into yen signs.
    // We emulate this behavior only when no font is explicitly specified.
    if (encoding && encoding->backslashAsCurrencySymbol() != '\\' && !fontDescription.isSpecifiedFont())
        return BackslashToYenSign;

    return NoConversion;
}
Example #9
0
PassRefPtr<FontData> FontFallbackList::getFontData(const FontDescription& fontDescription, int& familyIndex) const
{
    RefPtr<FontData> result;

    int startIndex = familyIndex;
    const FontFamily* startFamily = &fontDescription.family();
    for (int i = 0; startFamily && i < startIndex; i++)
        startFamily = startFamily->next();
    const FontFamily* currFamily = startFamily;
    while (currFamily && !result) {
        familyIndex++;
        if (currFamily->family().length()) {
            if (m_fontSelector)
                result = m_fontSelector->getFontData(fontDescription, currFamily->family());

            if (!result)
                result = FontCache::fontCache()->getFontData(fontDescription, currFamily->family());
        }
        currFamily = currFamily->next();
    }

    if (!currFamily)
        familyIndex = cAllFamiliesScanned;

    if (result || startIndex)
        return result.release();

    // If it's the primary font that we couldn't find, we try the following. In all other cases, we will
    // just use per-character system fallback.

    if (m_fontSelector) {
        // Try the user's preferred standard font.
        if (RefPtr<FontData> data = m_fontSelector->getFontData(fontDescription, FontFamilyNames::webkit_standard))
            return data.release();
    }

    // Still no result. Hand back our last resort fallback font.
    return FontCache::fontCache()->getLastResortFallbackFont(fontDescription);
}
Example #10
0
HRESULT STDMETHODCALLTYPE DOMElement::font(WebFontDescription* webFontDescription)
{
    if (!webFontDescription) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    ASSERT(m_element);

    WebCore::RenderObject* renderer = m_element->renderer();
    if (!renderer)
        return E_FAIL;

    FontDescription fontDescription = renderer->style()->font().fontDescription();
    AtomicString family = fontDescription.family().family();
    webFontDescription->family = family.characters();
    webFontDescription->familyLength = family.length();
    webFontDescription->size = fontDescription.computedSize();
    webFontDescription->bold = fontDescription.weight() >= WebCore::FontWeight600;
    webFontDescription->italic = fontDescription.italic();

    return S_OK;
}
FontPlatformData::FontPlatformData(const FontDescription& description, const AtomicString& familyName, const UChar* characters, int length, int wordSpacing, int letterSpacing)
    : m_data(new FontPlatformDataPrivate())
{
    using namespace EA::WebKit;

    EA::WebKit::TextStyle textStyle;  // We rather use the textStyle so we can pass in the spacing and the fx info directly. 
    InitTextStyle(textStyle);
    
	// Note by Arpit Baldeva:
	// The way WebCore expects us to handle creation of FontPlatformData is to take the familyName
	// in FontCacheEA.cpp and return a valid pointer only if that particular font can be created.
	// In CSS, one can specify multiple font families in order of preference. If you return NULL,
	// WebCore sends the next highest priority font. Note that it also converts generic font family
	// name (such as serif) to the one you specify as your default in the Settings (For example,
	// Times New Roman for us). So the system is supposed to be pretty simple.
	
	// The problem we have is that EAText wants to builds a priority array in one shot. Also, if you
	// request a font and it is not found, it may return one of the fallback fonts even though you may
	// have something down the priority order available in EAText.
	
	// So what we do here is build up that array.
	
	//-- Build FamilyName array ---
	ITextSystem* pTextSystem = GetTextSystem();
	const uint32_t familyNameArrayCapacity = pTextSystem->GetFamilyNameArrayCapacity();

	uint32_t i = 0;
	EAW_ASSERT_MSG(!familyName.isEmpty(), "Family name can never be empty");
	CopyFontFamilyName(textStyle.mFamilyNameArray[i],familyName);
    
	const FontFamily* pfontFamily = &(description.family());
	pfontFamily = pfontFamily->next();
	++i;

	const EA::WebKit::Parameters& params = EA::WebKit::GetParameters();
	
	// Here, we iterate through the list and copy the fonts to the destination array in the order of priority.
	// If we come across a generic font, we read it from the Params based on the generic family set in the description. 
	bool genericFontAdded = false;
	while(pfontFamily && i < familyNameArrayCapacity)
	{
		if(pfontFamily->family().startsWith("-webkit",true)) // A generic font family 
		{
			genericFontAdded = true;
			const char16_t* type = 0;
			switch(description.genericFamily())
			{
			case FontDescription::SerifFamily:
				type = params.mFontFamilySerif;
				break;

			case FontDescription::SansSerifFamily:
				type = params.mFontFamilySansSerif;
				break;

			case FontDescription::MonospaceFamily:
				type = params.mFontFamilyMonospace;
				break;

			case FontDescription::CursiveFamily:
				type = params.mFontFamilyCursive;
				break;

			case FontDescription::FantasyFamily:
				type = params.mFontFamilyFantasy;
				break;

			default:
			case FontDescription::NoFamily:
			case FontDescription::StandardFamily:
				type = params.mFontFamilyStandard;
				break;
			}

			if(type)
			{
				EA::Internal::Strcpy(textStyle.mFamilyNameArray[i],type);
				++i;
			}
			break;
		}

		CopyFontFamilyName(textStyle.mFamilyNameArray[i], pfontFamily->family());
		++i;
		pfontFamily = pfontFamily->next();
	}
	
	// If we went through all the fonts specified but a generic font was not added, we add the standard font as a fallback.
	// It is probably not a good practice to not specify a generic font family for any font but we deal with that situation here.
	if( i < familyNameArrayCapacity && !genericFontAdded)
	{
		EA::Internal::Strcpy(textStyle.mFamilyNameArray[i],params.mFontFamilyStandard);
		++i;
	}

	if(i < familyNameArrayCapacity)
		*textStyle.mFamilyNameArray[i] = 0;

	// verify that spacing can be used raw without size adjustments. 
    textStyle.mfLetterSpacing =  static_cast<float> (letterSpacing);   
    textStyle.mfWordSpacing =  static_cast<float> (wordSpacing);   

     // Size
    const float fFontSize = description.computedSize();
    const float fAdjustedFontSize = GetFontAdjustedSize(fFontSize); 
    textStyle.mfSize = fAdjustedFontSize;   
    
    // Italic
    const bool bItalic = description.italic();
    if(bItalic)
        textStyle.mStyle = EA::WebKit::kStyleItalic; 
      
    // Weight
    const WebCore::FontWeight fontWeight = description.weight();
    textStyle.mfWeight = GetFontAdjustedWeight(fontWeight);
    
    // Variant
    if(description.smallCaps())
        textStyle.mVariant = EA::WebKit::kVariantSmallCaps;

    // Smooth
    // We act like FireFox under Windows does with respect to sizes and weights.
    bool smooth = IsFontSmooth(fFontSize, description.fontSmoothing());
    if(smooth)
        textStyle.mSmooth = EA::WebKit::kSmoothEnabled;    

    // Effects.  
    const EA::WebKit::TextEffectData& effectData = description.getTextEffectData();
    textStyle.mTextEffectData = effectData;

    // Now get the requested font 
    if(pTextSystem)      
    { 
        IFont* pFont = pTextSystem->GetFont(textStyle, length ? characters[0] : ' ');
        EAW_ASSERT(pFont);
        m_data->mpFont = pFont;
    }
}
Example #12
0
// Given the desired base font, this will create a SimpleFontData for a specific
// font that can be used to render the given range of characters.
PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(
    const FontDescription& fontDescription,
    UChar32 character,
    const SimpleFontData* originalFontData,
    FontFallbackPriority fallbackPriority) {
  // First try the specified font with standard style & weight.
  if (fallbackPriority != FontFallbackPriority::EmojiEmoji &&
      (fontDescription.style() == FontStyleItalic ||
       fontDescription.weight() >= FontWeightBold)) {
    RefPtr<SimpleFontData> fontData =
        fallbackOnStandardFontStyle(fontDescription, character);
    if (fontData)
      return fontData;
  }

  UScriptCode script;
  const wchar_t* family = getFallbackFamily(
      character, fontDescription.genericFamily(), fontDescription.locale(),
      &script, fallbackPriority, m_fontManager.get());
  FontPlatformData* data = nullptr;
  if (family) {
    FontFaceCreationParams createByFamily(AtomicString(family, wcslen(family)));
    data = getFontPlatformData(fontDescription, createByFamily);
  }

  if ((!data || !data->fontContainsCharacter(character)) &&
      s_useSkiaFontFallback) {
    const char* bcp47Locale = nullptr;
    int localeCount = 0;
    // If the font description has a locale, use that. Otherwise, Skia will
    // fall back on the user's default locale.
    // TODO(kulshin): extract locale fallback logic from
    //   FontCacheAndroid.cpp and share that code
    if (fontDescription.locale()) {
      bcp47Locale = fontDescription.locale()->localeForSkFontMgr();
      localeCount = 1;
    }

    CString familyName = fontDescription.family().family().utf8();

    SkTypeface* typeface = m_fontManager->matchFamilyStyleCharacter(
        familyName.data(), fontDescription.skiaFontStyle(), &bcp47Locale,
        localeCount, character);
    if (typeface) {
      SkString skiaFamily;
      typeface->getFamilyName(&skiaFamily);
      FontFaceCreationParams createByFamily(AtomicString(skiaFamily.c_str()));
      data = getFontPlatformData(fontDescription, createByFamily);
    }
  }

  // Last resort font list : PanUnicode. CJK fonts have a pretty
  // large repertoire. Eventually, we need to scan all the fonts
  // on the system to have a Firefox-like coverage.
  // Make sure that all of them are lowercased.
  const static wchar_t* const cjkFonts[] = {
      L"arial unicode ms", L"ms pgothic", L"simsun", L"gulim", L"pmingliu",
      L"wenquanyi zen hei",  // Partial CJK Ext. A coverage but more widely
                             // known to Chinese users.
      L"ar pl shanheisun uni", L"ar pl zenkai uni",
      L"han nom a",  // Complete CJK Ext. A coverage.
      L"code2000"    // Complete CJK Ext. A coverage.
      // CJK Ext. B fonts are not listed here because it's of no use
      // with our current non-BMP character handling because we use
      // Uniscribe for it and that code path does not go through here.
  };

  const static wchar_t* const commonFonts[] = {
      L"tahoma", L"arial unicode ms", L"lucida sans unicode",
      L"microsoft sans serif", L"palatino linotype",
      // Six fonts below (and code2000 at the end) are not from MS, but
      // once installed, cover a very wide range of characters.
      L"dejavu serif", L"dejavu sasns", L"freeserif", L"freesans", L"gentium",
      L"gentiumalt", L"ms pgothic", L"simsun", L"gulim", L"pmingliu",
      L"code2000"};

  const wchar_t* const* panUniFonts = nullptr;
  int numFonts = 0;
  if (script == USCRIPT_HAN) {
    panUniFonts = cjkFonts;
    numFonts = WTF_ARRAY_LENGTH(cjkFonts);
  } else {
    panUniFonts = commonFonts;
    numFonts = WTF_ARRAY_LENGTH(commonFonts);
  }
  // Font returned from getFallbackFamily may not cover |character|
  // because it's based on script to font mapping. This problem is
  // critical enough for non-Latin scripts (especially Han) to
  // warrant an additional (real coverage) check with fontCotainsCharacter.
  int i;
  for (i = 0;
       (!data || !data->fontContainsCharacter(character)) && i < numFonts;
       ++i) {
    family = panUniFonts[i];
    FontFaceCreationParams createByFamily(AtomicString(family, wcslen(family)));
    data = getFontPlatformData(fontDescription, createByFamily);
  }

  // For font fallback we want to match the subpixel behavior of the original
  // font. Mixing subpixel and non-subpixel in the same text run looks really
  // odd and causes problems with preferred width calculations.
  if (data && originalFontData) {
    const FontPlatformData& platformData = originalFontData->platformData();
    data->setMinSizeForAntiAlias(platformData.minSizeForAntiAlias());
    data->setMinSizeForSubpixel(platformData.minSizeForSubpixel());
  }

  // When i-th font (0-base) in |panUniFonts| contains a character and
  // we get out of the loop, |i| will be |i + 1|. That is, if only the
  // last font in the array covers the character, |i| will be numFonts.
  // So, we have to use '<=" rather than '<' to see if we found a font
  // covering the character.
  if (i <= numFonts)
    return fontDataFromFontPlatformData(data, DoNotRetain);

  return nullptr;
}