Пример #1
0
FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicString& family)
{
// NB: The Windows wxFont constructor has two forms, one taking a wxSize (with pixels)
// and one taking an int (points). When points are used, Windows calculates
// a pixel size using an algorithm which causes the size to be way off. However,
// this is a moot issue on Linux and Mac as they only accept the point argument. So,
// we use the pixel size constructor on Windows, but we use point size on Linux and Mac.
#if __WXMSW__
    m_font = new FontHolder(new wxFont(   wxSize(0, -desc.computedPixelSize()),
                                          fontFamilyToWxFontFamily(desc.genericFamily()),
                                          italicToWxFontStyle(desc.italic()),
                                          fontWeightToWxFontWeight(desc.weight()),
                                          false,
                                          family.string()
                                      )
                           );
#else
    m_font = new FontHolder(new wxFont(   desc.computedPixelSize(),
                                          fontFamilyToWxFontFamily(desc.genericFamily()),
                                          italicToWxFontStyle(desc.italic()),
                                          fontWeightToWxFontWeight(desc.weight()),
                                          false,
                                          family.string()
                                      )
                           );
#endif
    m_fontState = VALID;

}
Пример #2
0
HRESULT STDMETHODCALLTYPE DOMElement::font(WebFontDescription* webFontDescription)
{
    if (!webFontDescription) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    ASSERT(m_element);

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

    FontDescription fontDescription = renderer->style().fontCascade().fontDescription();
    AtomicString family = fontDescription.firstFamily();

    // FIXME: This leaks. Delete this whole function to get rid of the leak.
    UChar* familyCharactersBuffer = new UChar[family.length()];
    StringView(family.string()).getCharactersWithUpconvert(familyCharactersBuffer);

    webFontDescription->family = familyCharactersBuffer;
    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, int wordSpacing, int letterSpacing)
    : m_data(adoptRef(new FontPlatformDataPrivate()))
{
    QFont font;
    int requestedSize = description.computedPixelSize();
    font.setFamily(familyName);
    if (requestedSize)
    font.setPixelSize(requestedSize);
    font.setItalic(description.italic());
    font.setWeight(toQFontWeight(description.weight()));
    font.setWordSpacing(wordSpacing);
    font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing);
    if (description.fontSmoothing() == NoSmoothing)
        font.setStyleStrategy(QFont::NoAntialias);
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
    if (description.fontSmoothing() == AutoSmoothing && !Font::shouldUseSmoothing())
        font.setStyleStrategy(QFont::NoAntialias);
#endif

    m_data->bold = font.bold();
    // WebKit allows font size zero but QFont does not. We will return
    // m_data->size if a font size of zero is requested and pixelSize()
    // otherwise.
    m_data->size = (!requestedSize) ? requestedSize : font.pixelSize();
    m_data->rawFont = QRawFont::fromFont(font, QFontDatabase::Any);
}
Пример #4
0
FontPlatformData::FontPlatformData(const FontDescription& description, const AtomicString& familyName, int wordSpacing, int letterSpacing)
    : m_data(adoptRef(new FontPlatformDataPrivate()))
{
    QFont& font = m_data->font;
    int requestedSize = qRound(description.computedPixelSize());
    font.setFamily(familyName);
    font.setPixelSize(qRound(requestedSize));
    font.setItalic(description.italic());
    font.setWeight(toQFontWeight(description.weight()));
    font.setWordSpacing(wordSpacing);
    font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing);
    const bool smallCaps = description.smallCaps();
    font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase);
    // Commented out to work around webkit bug 93263
    //font.setStyleStrategy(QFont::ForceIntegerMetrics);

    m_data->bold = font.bold();
    // WebKit allows font size zero but QFont does not. We will return
    // m_data->size if a font size of zero is requested and pixelSize()
    // otherwise.
    m_data->size = (!requestedSize) ? requestedSize : font.pixelSize();
#if HAVE(QRAWFONT)
    m_data->rawFont = QRawFont::fromFont(font, QFontDatabase::Any);
#endif
}
Пример #5
0
std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
    // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm)
    // says that we must find an exact match for font family, slant (italic or oblique can be used)
    // and font weight (we only match bold/non-bold here).
    RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate());
    // Never choose unscalable fonts, as they pixelate when displayed at different sizes.
    FcPatternAddBool(pattern.get(), FC_SCALABLE, FcTrue);
    String familyNameString(getFamilyNameStringFromFamily(family));
    if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data())))
        return nullptr;

    bool italic = fontDescription.italic();
    if (!FcPatternAddInteger(pattern.get(), FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN))
        return nullptr;
    if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fontWeightToFontconfigWeight(fontDescription.weight())))
        return nullptr;
    if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fontDescription.computedPixelSize()))
        return nullptr;

    // The strategy is originally from Skia (src/ports/SkFontHost_fontconfig.cpp):

    // Allow Fontconfig to do pre-match substitution. Unless we are accessing a "fallback"
    // family like "sans," this is the only time we allow Fontconfig to substitute one
    // family name for another (i.e. if the fonts are aliased to each other).
    FcConfigSubstitute(0, pattern.get(), FcMatchPattern);
    FcDefaultSubstitute(pattern.get());

    FcChar8* fontConfigFamilyNameAfterConfiguration;
    FcPatternGetString(pattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterConfiguration);
    String familyNameAfterConfiguration = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterConfiguration));

    FcResult fontConfigResult;
    RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(0, pattern.get(), &fontConfigResult));
    if (!resultPattern) // No match.
        return nullptr;

    FcChar8* fontConfigFamilyNameAfterMatching;
    FcPatternGetString(resultPattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterMatching);
    String familyNameAfterMatching = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterMatching));

    // If Fontconfig gave use a different font family than the one we requested, we should ignore it
    // and allow WebCore to give us the next font on the CSS fallback list. The only exception is if
    // this family name is a commonly used generic family.
    if (!equalIgnoringCase(familyNameAfterConfiguration, familyNameAfterMatching)
        && !(equalIgnoringCase(familyNameString, "sans") || equalIgnoringCase(familyNameString, "sans-serif")
          || equalIgnoringCase(familyNameString, "serif") || equalIgnoringCase(familyNameString, "monospace")
          || equalIgnoringCase(familyNameString, "fantasy") || equalIgnoringCase(familyNameString, "cursive")))
        return nullptr;

    // Verify that this font has an encoding compatible with Fontconfig. Fontconfig currently
    // supports three encodings in FcFreeTypeCharIndex: Unicode, Symbol and AppleRoman.
    // If this font doesn't have one of these three encodings, don't select it.
    auto platformData = std::make_unique<FontPlatformData>(resultPattern.get(), fontDescription);
    if (!platformData->hasCompatibleCharmap())
        return nullptr;

    return platformData;
}
Пример #6
0
FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicString& family)
{
// NB: The Windows wxFont constructor has two forms, one taking a wxSize (with pixels)
// and one taking an int (points). When points are used, Windows calculates
// a pixel size using an algorithm which causes the size to be way off. However,
// this is a moot issue on Linux and Mac as they only accept the point argument. So,
// we use the pixel size constructor on Windows, but we use point size on Linux and Mac.
#if __WXMSW__
    m_font = adoptRef(new FontHolder(new wxFont(   wxSize(0, -desc.computedPixelSize()), 
                                fontFamilyToWxFontFamily(desc.genericFamily()), 
                                italicToWxFontStyle(desc.italic()),
                                fontWeightToWxFontWeight(desc.weight()),
                                false,
                                family.string()
                            )
                        )); 
#else
    m_font = adoptRef(new FontHolder(new wxFont(   desc.computedPixelSize(), 
                                fontFamilyToWxFontFamily(desc.genericFamily()), 
                                italicToWxFontStyle(desc.italic()),
                                fontWeightToWxFontWeight(desc.weight()),
                                false,
                                family.string()
                            )
                        )); 
#endif
#if OS(DARWIN)
#if !wxOSX_USE_CORE_TEXT
#if wxCHECK_VERSION(2,9,0)
    m_atsuFontID = m_font->font()->OSXGetATSUFontID();
#else
    m_atsuFontID = m_font->font()->MacGetATSUFontID();
#endif
#endif
    m_nsFont = 0;
    cacheNSFont();
#endif
    m_size = desc.computedPixelSize();
    m_fontState = VALID;
    m_size = desc.computedPixelSize();
}
Пример #7
0
void FontPlatformData::initializeWithFontFace(cairo_font_face_t* fontFace, const FontDescription& fontDescription)
{
    cairo_font_options_t* options = getDefaultFontOptions();

    cairo_matrix_t ctm;
    cairo_matrix_init_identity(&ctm);

    // Scaling a font with width zero size leads to a failed cairo_scaled_font_t instantiations.
    // Instead we scale we scale the font to a very tiny size and just abort rendering later on.
    float realSize = m_size ? m_size : 1;

    cairo_matrix_t fontMatrix;
    if (!m_pattern)
        cairo_matrix_init_scale(&fontMatrix, realSize, realSize);
    else {

        setCairoFontOptionsFromFontConfigPattern(options, m_pattern.get());

        // FontConfig may return a list of transformation matrices with the pattern, for instance,
        // for fonts that are oblique. We use that to initialize the cairo font matrix.
        FcMatrix fontConfigMatrix, *tempFontConfigMatrix;
        FcMatrixInit(&fontConfigMatrix);

        // These matrices may be stacked in the pattern, so it's our job to get them all and multiply them.
        for (int i = 0; FcPatternGetMatrix(m_pattern.get(), FC_MATRIX, i, &tempFontConfigMatrix) == FcResultMatch; i++)
            FcMatrixMultiply(&fontConfigMatrix, &fontConfigMatrix, tempFontConfigMatrix);
        cairo_matrix_init(&fontMatrix, fontConfigMatrix.xx, -fontConfigMatrix.yx,
                          -fontConfigMatrix.xy, fontConfigMatrix.yy, 0, 0);

        // We requested an italic font, but Fontconfig gave us one that was neither oblique nor italic.
        int actualFontSlant;
        if (fontDescription.italic() && FcPatternGetInteger(m_pattern.get(), FC_SLANT, 0, &actualFontSlant) == FcResultMatch)
            m_syntheticOblique = actualFontSlant == FC_SLANT_ROMAN;

        // The matrix from FontConfig does not include the scale. 
        cairo_matrix_scale(&fontMatrix, realSize, realSize);

    }

    if (syntheticOblique()) {
        static const float syntheticObliqueSkew = -tanf(14 * acosf(0) / 90);
        cairo_matrix_t skew = {1, 0, syntheticObliqueSkew, 1, 0, 0};
        cairo_matrix_multiply(&fontMatrix, &skew, &fontMatrix);
    }

    m_horizontalOrientationMatrix = fontMatrix;
    if (m_orientation == Vertical)
        rotateCairoMatrixForVerticalOrientation(&fontMatrix);

    m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options);
    cairo_font_options_destroy(options);
}
Пример #8
0
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
    : m_font(new QFont("Times New Roman", 12))
{
    m_font->setFamily(familyName.domString());
    m_font->setPixelSize(qRound(fontDescription.computedSize()));
    m_font->setItalic(fontDescription.italic());
    if (fontDescription.bold()) {
        // Qt's Bold is 75, Webkit is 63.
        m_font->setWeight(QFont::Bold);
    } else {
        m_font->setWeight(fontDescription.weight());
    }
}
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
    : m_pattern(0)
    , m_size(fontDescription.computedSize())
    , m_syntheticBold(false)
    , m_syntheticOblique(false)
    , m_scaledFont(0)
{
    if (fontDescription.italic()) {
        m_pixelFont = &NormalItalicPixelFont;
        m_syntheticOblique = true;
    } else if (fontDescription.weight() >= FontWeightBold) {
        m_pixelFont = &NormalBoldPixelFont;
        m_syntheticBold = true;
    } else 
        m_pixelFont = &NormalPixelFont;
    FontPlatformData::init();
}
Пример #10
0
static void FillLogFont(const FontDescription& fontDescription, LOGFONT* winfont)
{
    // The size here looks unusual.  The negative number is intentional.
    // Unlike WebKit trunk, we don't multiply the size by 32.  That seems to be
    // some kind of artifact of their CG backend, or something.
    winfont->lfHeight = -fontDescription.computedPixelSize();
    winfont->lfWidth = 0;
    winfont->lfEscapement = 0;
    winfont->lfOrientation = 0;
    winfont->lfUnderline = false;
    winfont->lfStrikeOut = false;
    winfont->lfCharSet = DEFAULT_CHARSET;
    winfont->lfOutPrecision = OUT_TT_ONLY_PRECIS;
    winfont->lfQuality = PlatformSupport::layoutTestMode() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY; // Honor user's desktop settings.
    winfont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
    winfont->lfItalic = fontDescription.italic();
    winfont->lfWeight = toGDIFontWeight(fontDescription.weight());
}
FontPlatformData::FontPlatformData(const FontDescription& description, const AtomicString& familyName, int wordSpacing, int letterSpacing)
    : m_data(new FontPlatformDataPrivate())
{
    QFont& font = m_data->font;
    font.setFamily(familyName);
    font.setPixelSize(qRound(description.computedSize()));
    font.setItalic(description.italic());
    font.setWeight(toQFontWeight(description.weight()));
    font.setWordSpacing(wordSpacing);
    font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing);
    const bool smallCaps = description.smallCaps();
    font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase);
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
    font.setStyleStrategy(QFont::ForceIntegerMetrics);
#endif

    m_data->bold = font.bold();
    m_data->size = font.pointSizeF();
}
Пример #12
0
HRESULT STDMETHODCALLTYPE DOMElement::font(WebFontDescription* webFontDescription)
{
    if (!webFontDescription) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    ASSERT(m_element);

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

    FontDescription fontDescription = renderer->style().font().fontDescription();
    AtomicString family = fontDescription.firstFamily();
    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;
}
Пример #13
0
 FontPlatformPrivateData(const FontDescription& fontDescription, const AtomicString& family)
     : m_reference(1)
     , m_size(fontDescription.computedPixelSize())
     , m_fontDescription(fontDescription)
     , m_family(family)
     , m_fontScaledWidth(0)
     , m_fontScaledHeight(0)
     , m_disabled(!fontDescription.specifiedSize())
 {
     m_rootFontData = FixedSizeFontData::create(family, toGDIFontWeight(fontDescription.weight()), fontDescription.italic());
 }
Пример #14
0
std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
    // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm)
    // says that we must find an exact match for font family, slant (italic or oblique can be used)
    // and font weight (we only match bold/non-bold here).
    RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate());
    // Never choose unscalable fonts, as they pixelate when displayed at different sizes.
    FcPatternAddBool(pattern.get(), FC_SCALABLE, FcTrue);
    String familyNameString(getFamilyNameStringFromFamily(family));
    if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data())))
        return nullptr;

    bool italic = fontDescription.italic();
    if (!FcPatternAddInteger(pattern.get(), FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN))
        return nullptr;
    if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fontWeightToFontconfigWeight(fontDescription.weight())))
        return nullptr;
    if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fontDescription.computedPixelSize()))
        return nullptr;

    // The strategy is originally from Skia (src/ports/SkFontHost_fontconfig.cpp):
    //
    // We do not normally allow fontconfig to substitute one font family for another, since this
    // would break CSS font family fallback: the website should be in control of fallback. During
    // normal font matching, the only font family substitution permitted is for generic families
    // (sans, serif, monospace) or for strongly-aliased fonts (which are to be treated as
    // effectively identical). This is because the font matching step is designed to always find a
    // match for the font, which we don't want.
    //
    // Fontconfig is used in two stages: (1) configuration and (2) matching. During the
    // configuration step, before any matching occurs, we allow arbitrary family substitutions,
    // since this is an exact matter of respecting the user's font configuration.
    FcConfigSubstitute(nullptr, pattern.get(), FcMatchPattern);
    FcDefaultSubstitute(pattern.get());

    FcChar8* fontConfigFamilyNameAfterConfiguration;
    FcPatternGetString(pattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterConfiguration);
    String familyNameAfterConfiguration = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterConfiguration));

    FcResult fontConfigResult;
    RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(nullptr, pattern.get(), &fontConfigResult));
    if (!resultPattern) // No match.
        return nullptr;

    FcChar8* fontConfigFamilyNameAfterMatching;
    FcPatternGetString(resultPattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterMatching);
    String familyNameAfterMatching = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterMatching));

    // If Fontconfig gave us a different font family than the one we requested, we should ignore it
    // and allow WebCore to give us the next font on the CSS fallback list. The exceptions are if
    // this family name is a commonly-used generic family, or if the families are strongly-aliased.
    // Checking for a strong alias comes last, since it is slow.
    if (!equalIgnoringCase(familyNameAfterConfiguration, familyNameAfterMatching)
        && !(equalIgnoringCase(familyNameString, "sans") || equalIgnoringCase(familyNameString, "sans-serif")
          || equalIgnoringCase(familyNameString, "serif") || equalIgnoringCase(familyNameString, "monospace")
          || equalIgnoringCase(familyNameString, "fantasy") || equalIgnoringCase(familyNameString, "cursive"))
        && !areStronglyAliased(familyNameAfterConfiguration, familyNameAfterMatching))
        return nullptr;

    // Verify that this font has an encoding compatible with Fontconfig. Fontconfig currently
    // supports three encodings in FcFreeTypeCharIndex: Unicode, Symbol and AppleRoman.
    // If this font doesn't have one of these three encodings, don't select it.
    auto platformData = std::make_unique<FontPlatformData>(resultPattern.get(), fontDescription);
    if (!platformData->hasCompatibleCharmap())
        return nullptr;

    return platformData;
}
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
    : m_pattern(0)
    , m_fallbacks(0)
    , m_size(fontDescription.computedSize())
    , m_syntheticBold(false)
    , m_syntheticOblique(false)
    , m_scaledFont(0)
    , m_face(0)
{
    FontPlatformData::init();

    CString familyNameString = familyName.string().utf8();
    const char* fcfamily = familyNameString.data();

    int fcslant = FC_SLANT_ROMAN;
    // FIXME: Map all FontWeight values to fontconfig weights.
    int fcweight = FC_WEIGHT_NORMAL;
    float fcsize = fontDescription.computedSize();
    if (fontDescription.italic())
        fcslant = FC_SLANT_ITALIC;
    if (fontDescription.weight() >= FontWeight600)
        fcweight = FC_WEIGHT_BOLD;

    FcConfig *config = FcConfigGetCurrent();

    //printf("family = %s\n", fcfamily);

    int type = fontDescription.genericFamily();

    FcPattern* pattern = FcPatternCreate();
    
    if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
        goto freePattern;

    switch (type) {
        case FontDescription::SerifFamily:
            fcfamily = "serif";
            break;
        case FontDescription::SansSerifFamily:
            fcfamily = "sans-serif";
            break;
        case FontDescription::MonospaceFamily:
            fcfamily = "monospace";
            break;
        case FontDescription::NoFamily:
        case FontDescription::StandardFamily:
        default:
            fcfamily = "sans-serif";
    }

    if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
        goto freePattern;
    if (!FcPatternAddInteger(pattern, FC_SLANT, fcslant))
        goto freePattern;
    if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight))
        goto freePattern;
    if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fcsize))
        goto freePattern;

    FcConfigSubstitute(config, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult fcresult;
    m_pattern = FcFontMatch(config, pattern, &fcresult);
    FcPatternReference(m_pattern);
    // FIXME: should we set some default font?
    if (!m_pattern)
        goto freePattern;

    FcChar8 *fc_filename;
    char *filename;
    int id;
    id = 0;

    if (FcPatternGetString(m_pattern, FC_FILE, 0, &fc_filename) != FcResultMatch) {
        LOG(FontEngine, "cannot retrieve font\n");
        goto freePattern;
    }

    filename = (char *) fc_filename; //use C cast as FcChar is a fontconfig type
    //printf("filename = %s\n", filename);

    if (FcPatternGetInteger(m_pattern, FC_INDEX, 0, &id) != FcResultMatch) {
        LOG(FontEngine, "cannot retrieve font index\n");
        goto freePattern;
    }
    
    if (FT_Error error = FT_New_Face(m_library, filename, id, &m_face)) {
    //if (FT_Error error = FT_New_Face(m_library, too, id, &m_face)) {
        LOG(FontEngine, "fail to open fonti %s with index %d (error = 0x%x)\n", filename, id, error);
        m_face = 0;
        goto freePattern;
    }

    FT_Set_Pixel_Sizes(m_face, 0, static_cast<uint> (fontDescription.computedSize()));
    //DBGML(MODULE_FONTS, LEVEL_INFO, "open font %s with size %d\n", filename, static_cast<uint> (fontDescription.specifiedSize()));

freePattern:
    FcPatternDestroy(pattern);
    FcConfigDestroy(config);
}
Пример #16
0
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const UChar *characters, int length)
    : m_context(0)
    , m_font(0)
    , m_size(fontDescription.computedSize())
    , m_syntheticBold(false)
    , m_syntheticOblique(false)
    , m_scaledFont(0)
{
    FontPlatformData::init();

    const UChar character = characters[0];

    char const *family;
    switch (fontDescription.genericFamily()) {
        case FontDescription::SerifFamily:
            family = "serif";
            break;
        case FontDescription::SansSerifFamily:
            family = "sans";
            break;
        case FontDescription::MonospaceFamily:
            family = "monospace";
            break;
        case FontDescription::NoFamily:
        case FontDescription::StandardFamily:
        default:
            family = "sans";
            break;
    }

    m_context = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(m_fontMap));

    PangoFontDescription* description = pango_font_description_new();

    pango_font_description_set_absolute_size(description, fontDescription.computedSize() * PANGO_SCALE);
    if (fontDescription.weight() >= FontWeight600)
        pango_font_description_set_weight(description, PANGO_WEIGHT_BOLD);
    if (fontDescription.italic())
        pango_font_description_set_style(description, PANGO_STYLE_ITALIC);

    pango_font_description_set_family(description, family);
    pango_context_set_font_description(m_context, description);

    PangoFontset *fset = pango_font_map_load_fontset (m_fontMap, m_context, description, NULL); 

    // Get the font from the fontset which contains the best glyph for this character
    m_font = pango_fontset_get_font(fset, (guint)character);

#if PANGO_VERSION_CHECK(1,18,0)
    if (m_font)
        m_scaledFont = cairo_scaled_font_reference(pango_cairo_font_get_scaled_font(PANGO_CAIRO_FONT(m_font)));
#else
    // This compatibility code for older versions of Pango is not well-tested.
    if (m_font) {
        PangoFcFont* fcfont = PANGO_FC_FONT(m_font);
        cairo_font_face_t* face = cairo_ft_font_face_create_for_pattern(fcfont->font_pattern);
        double size;
        if (FcPatternGetDouble(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
          size = 12.0;
        cairo_matrix_t fontMatrix;
        cairo_matrix_init_scale(&fontMatrix, size, size);
        cairo_font_options_t* fontOptions;
        if (pango_cairo_context_get_font_options(m_context))
          fontOptions = cairo_font_options_copy(pango_cairo_context_get_font_options(m_context));
        else
          fontOptions = cairo_font_options_create();
        cairo_matrix_t ctm;
        cairo_matrix_init_identity(&ctm);
        m_scaledFont = cairo_scaled_font_create(face, &fontMatrix, &ctm, fontOptions);
        cairo_font_options_destroy(fontOptions);
        cairo_font_face_destroy(face);
    }
#endif

    pango_font_description_free(description);
}
FontPlatformData::FontPlatformData(const FontDescription& in_desc, const AtomicString& in_family)
{
    int size = 0;
    int weight = WKC_FONT_WEIGHT_NORMAL;
    int family = WKC_FONT_FAMILY_NONE;
    bool italic = in_desc.italic();

    switch (in_desc.genericFamily()) {
    case FontDescription::NoFamily:
        family = WKC_FONT_FAMILY_NONE;
        break;
    case FontDescription::StandardFamily:
        family = WKC_FONT_FAMILY_STANDARD;
        break;
    case FontDescription::SerifFamily:
        family = WKC_FONT_FAMILY_SERIF;
        break;
    case FontDescription::SansSerifFamily:
        family = WKC_FONT_FAMILY_SANSSERIF;
        break;
    case FontDescription::MonospaceFamily:
        family = WKC_FONT_FAMILY_MONOSPACE;
        break;
    case FontDescription::CursiveFamily:
        family = WKC_FONT_FAMILY_CURSIVE;
        break;
    case FontDescription::FantasyFamily:
        family = WKC_FONT_FAMILY_FANTASY;
        break;
    }
    switch (in_desc.weight()) {
    case FontWeight100:
        weight = WKC_FONT_WEIGHT_100;
        break;
    case FontWeight200:
        weight = WKC_FONT_WEIGHT_200;
        break;
    case FontWeight300:
        weight = WKC_FONT_WEIGHT_300;
        break;
    case FontWeight400:
        weight = WKC_FONT_WEIGHT_400;
        break;
    case FontWeight500:
        weight = WKC_FONT_WEIGHT_500;
        break;
    case FontWeight600:
        weight = WKC_FONT_WEIGHT_600;
        break;
    case FontWeight700:
        weight = WKC_FONT_WEIGHT_700;
        break;
    case FontWeight800:
        weight = WKC_FONT_WEIGHT_800;
        break;
    case FontWeight900:
        weight = WKC_FONT_WEIGHT_900;
        break;
    }
    m_requestSize = in_desc.computedPixelSize();
    size = m_requestSize;
    m_weight = weight;
    m_italic = italic;

    m_font = wkcFontNewPeer(size, weight, italic, family, in_family.string().utf8().data());
    m_fontState = VALID;

    m_createdSize = wkcFontGetSizePeer(m_font);
    m_ascent = wkcFontGetAscentPeer(m_font);
    m_descent = wkcFontGetDescentPeer(m_font);
    m_lineSpacing = wkcFontGetLineSpacingPeer(m_font);
    m_canScale = wkcFontCanScalePeer(m_font);

    m_scale = 1.f;
    if (gEnableScalingMonosizeFont && m_createdSize) {
        m_scale = (float)m_requestSize / (float)m_createdSize;
    }
    m_iscale = 1.f / m_scale;

    m_hashValue = calculateHash();
}
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
    : m_context(0)
    , m_font(0)
    , m_size(fontDescription.computedSize())
    , m_syntheticBold(false)
    , m_syntheticOblique(false)
    , m_scaledFont(0)
{
    FontPlatformData::init();

    CString stored_family = familyName.string().utf8();
    char const* families[] = {
      stored_family.data(),
      NULL
    };

    switch (fontDescription.genericFamily()) {
    case FontDescription::SerifFamily:
        families[1] = "serif";
        break;
    case FontDescription::SansSerifFamily:
        families[1] = "sans";
        break;
    case FontDescription::MonospaceFamily:
        families[1] = "monospace";
        break;
    case FontDescription::NoFamily:
    case FontDescription::StandardFamily:
    default:
        families[1] = "sans";
        break;
    }

    PangoFontDescription* description = pango_font_description_new();
    pango_font_description_set_absolute_size(description, fontDescription.computedSize() * PANGO_SCALE);

    // FIXME: Map all FontWeight values to Pango font weights.
    if (fontDescription.weight() >= FontWeight600)
        pango_font_description_set_weight(description, PANGO_WEIGHT_BOLD);
    if (fontDescription.italic())
        pango_font_description_set_style(description, PANGO_STYLE_ITALIC);

#if PANGO_VERSION_CHECK(1,21,5)   // deprecated in 1.21
    m_context = pango_font_map_create_context(m_fontMap);
#else
    m_context = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(m_fontMap));
#endif
    for (unsigned int i = 0; !m_font && i < G_N_ELEMENTS(families); i++) {
        pango_font_description_set_family(description, families[i]);
        pango_context_set_font_description(m_context, description);
        m_font = pango_font_map_load_font(m_fontMap, m_context, description);
    }

#if PANGO_VERSION_CHECK(1,18,0)
    if (m_font)
        m_scaledFont = cairo_scaled_font_reference(pango_cairo_font_get_scaled_font(PANGO_CAIRO_FONT(m_font)));
#else
    // This compatibility code for older versions of Pango is not well-tested.
    if (m_font) {
        PangoFcFont* fcfont = PANGO_FC_FONT(m_font);
        cairo_font_face_t* face = cairo_ft_font_face_create_for_pattern(fcfont->font_pattern);
        double size;
        if (FcPatternGetDouble(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
            size = 12.0;
        cairo_matrix_t fontMatrix;
        cairo_matrix_init_scale(&fontMatrix, size, size);
        cairo_font_options_t* fontOptions;
        if (pango_cairo_context_get_font_options(m_context))
            fontOptions = cairo_font_options_copy(pango_cairo_context_get_font_options(m_context));
        else
            fontOptions = cairo_font_options_create();
        cairo_matrix_t ctm;
        cairo_matrix_init_identity(&ctm);
        m_scaledFont = cairo_scaled_font_create(face, &fontMatrix, &ctm, fontOptions);
        cairo_font_options_destroy(fontOptions);
        cairo_font_face_destroy(face);
    }
#endif
    pango_font_description_free(description);
}
Пример #19
0
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;
    }
}