⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svgfont.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                if (SVGMissingGlyphElement* element = m_fontElement->firstMissingGlyphElement()) {                    // <missing-glyph> element support                    identifier = SVGGlyphElement::buildGenericGlyphIdentifier(element);                    SVGGlyphElement::inheritUnspecifiedAttributes(identifier, m_fontData);                    identifier.isValid = true;                } else {                    // Fallback to system font fallback                    TextRun subRun(run);                    subRun.setText(subRun.data(i), 1);                    (*m_walkerMissingGlyphCallback)(subRun, m_walkerData);                    continue;                }            }            if (!(*m_walkerCallback)(identifier, m_walkerData))                break;            foundGlyph = false;        }    }private:    const SVGFontData* m_fontData;    SVGFontElement* m_fontElement;    SVGTextRunData& m_walkerData;    SVGTextRunWalkerCallback m_walkerCallback;    SVGTextRunWalkerMissingGlyphCallback m_walkerMissingGlyphCallback;};// Callback & data structures to compute the width of text using SVG Fontsstruct SVGTextRunWalkerMeasuredLengthData {    int at;    int from;    int to;    int extraCharsAvailable;    int charsConsumed;    String glyphName;    float scale;    float length;    const Font* font;};static bool floatWidthUsingSVGFontCallback(const SVGGlyphIdentifier& identifier, SVGTextRunWalkerMeasuredLengthData& data){    if (data.at >= data.from && data.at < data.to)        data.length += identifier.horizontalAdvanceX * data.scale;    data.at++;    return data.at < data.to;}static void floatWidthMissingGlyphCallback(const TextRun& run, SVGTextRunWalkerMeasuredLengthData& data){    // Handle system font fallback    FontDescription fontDescription(data.font->fontDescription());    fontDescription.setFamily(FontFamily());    Font font(fontDescription, 0, 0); // spacing handled by SVG text code.    font.update(data.font->fontSelector());    data.length += font.floatWidth(run);}SVGFontElement* Font::svgFont() const{     if (!isSVGFont())        return 0;    SVGFontElement* fontElement = 0;    SVGFontFaceElement* fontFaceElement = 0;    if (svgFontAndFontFaceElementForFontData(primaryFont(), fontFaceElement, fontElement))        return fontElement;        return 0;}static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun& run, int extraCharsAvailable, int from, int to, int& charsConsumed, String& glyphName){    int newFrom = to > from ? from : to;    int newTo = to > from ? to : from;    from = newFrom;    to = newTo;    SVGFontElement* fontElement = 0;    SVGFontFaceElement* fontFaceElement = 0;    if (const SVGFontData* fontData = svgFontAndFontFaceElementForFontData(font->primaryFont(), fontFaceElement, fontElement)) {        if (!fontElement)            return 0.0f;        SVGTextRunWalkerMeasuredLengthData data;        data.font = font;        data.at = from;        data.from = from;        data.to = to;        data.extraCharsAvailable = extraCharsAvailable;        data.charsConsumed = 0;        data.scale = convertEmUnitToPixel(font->size(), fontFaceElement->unitsPerEm(), 1.0f);        data.length = 0.0f;        String language;        bool isVerticalText = false; // Holds true for HTML text        // TODO: language matching & svg glyphs should be possible for HTML text, too.        if (RenderObject* renderObject = run.referencingRenderObject()) {            isVerticalText = isVerticalWritingMode(renderObject->style()->svgStyle());            if (SVGElement* element = static_cast<SVGElement*>(renderObject->node()))                language = element->getAttribute(XMLNames::langAttr);        }        SVGTextRunWalker<SVGTextRunWalkerMeasuredLengthData> runWalker(fontData, fontElement, data, floatWidthUsingSVGFontCallback, floatWidthMissingGlyphCallback);        runWalker.walk(run, isVerticalText, language, 0, run.length());        charsConsumed = data.charsConsumed;        glyphName = data.glyphName;        return data.length;    }    return 0.0f;}float Font::floatWidthUsingSVGFont(const TextRun& run) const{    int charsConsumed;    String glyphName;    return floatWidthOfSubStringUsingSVGFont(this, run, 0, 0, run.length(), charsConsumed, glyphName);}float Font::floatWidthUsingSVGFont(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const{    return floatWidthOfSubStringUsingSVGFont(this, run, extraCharsAvailable, 0, run.length(), charsConsumed, glyphName);}// Callback & data structures to draw text using SVG Fontsstruct SVGTextRunWalkerDrawTextData {    int extraCharsAvailable;    int charsConsumed;    String glyphName;    Vector<SVGGlyphIdentifier> glyphIdentifiers;    Vector<UChar> fallbackCharacters;};static bool drawTextUsingSVGFontCallback(const SVGGlyphIdentifier& identifier, SVGTextRunWalkerDrawTextData& data){    data.glyphIdentifiers.append(identifier);    return true;}static void drawTextMissingGlyphCallback(const TextRun& run, SVGTextRunWalkerDrawTextData& data){    ASSERT(run.length() == 1);    data.glyphIdentifiers.append(SVGGlyphIdentifier());    data.fallbackCharacters.append(run[0]);}void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run,                                 const FloatPoint& point, int from, int to) const{    SVGFontElement* fontElement = 0;    SVGFontFaceElement* fontFaceElement = 0;    if (const SVGFontData* fontData = svgFontAndFontFaceElementForFontData(primaryFont(), fontFaceElement, fontElement)) {        if (!fontElement)            return;        SVGTextRunWalkerDrawTextData data;        FloatPoint currentPoint = point;        float scale = convertEmUnitToPixel(size(), fontFaceElement->unitsPerEm(), 1.0f);        SVGPaintServer* activePaintServer = run.activePaintServer();        // If renderObject is not set, we're dealing for HTML text rendered using SVG Fonts.        if (!run.referencingRenderObject()) {            ASSERT(!activePaintServer);            // TODO: We're only supporting simple filled HTML text so far.            SVGPaintServerSolid* solidPaintServer = SVGPaintServer::sharedSolidPaintServer();            solidPaintServer->setColor(context->fillColor());            activePaintServer = solidPaintServer;        }        ASSERT(activePaintServer);        int charsConsumed;        String glyphName;        bool isVerticalText = false;        float xStartOffset = floatWidthOfSubStringUsingSVGFont(this, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed, glyphName);        FloatPoint glyphOrigin;        String language;        // TODO: language matching & svg glyphs should be possible for HTML text, too.        if (run.referencingRenderObject()) {            isVerticalText = isVerticalWritingMode(run.referencingRenderObject()->style()->svgStyle());                if (SVGElement* element = static_cast<SVGElement*>(run.referencingRenderObject()->node()))                language = element->getAttribute(XMLNames::langAttr);        }        if (!isVerticalText) {            glyphOrigin.setX(fontData->horizontalOriginX() * scale);            glyphOrigin.setY(fontData->horizontalOriginY() * scale);        }        data.extraCharsAvailable = 0;        data.charsConsumed = 0;        SVGTextRunWalker<SVGTextRunWalkerDrawTextData> runWalker(fontData, fontElement, data, drawTextUsingSVGFontCallback, drawTextMissingGlyphCallback);        runWalker.walk(run, isVerticalText, language, from, to);        SVGPaintTargetType targetType = context->textDrawingMode() == cTextStroke ? ApplyToStrokeTargetType : ApplyToFillTargetType;        unsigned numGlyphs = data.glyphIdentifiers.size();        unsigned fallbackCharacterIndex = 0;        for (unsigned i = 0; i < numGlyphs; ++i) {            const SVGGlyphIdentifier& identifier = data.glyphIdentifiers[run.rtl() ? numGlyphs - i - 1 : i];            if (identifier.isValid) {                // FIXME: Support arbitary SVG content as glyph (currently limited to <glyph d="..."> situations).                if (!identifier.pathData.isEmpty()) {                    context->save();                    if (isVerticalText) {                        glyphOrigin.setX(identifier.verticalOriginX * scale);                        glyphOrigin.setY(identifier.verticalOriginY * scale);                    }                    context->translate(xStartOffset + currentPoint.x() + glyphOrigin.x(), currentPoint.y() + glyphOrigin.y());                    context->scale(FloatSize(scale, -scale));                    context->beginPath();                    context->addPath(identifier.pathData);                    if (activePaintServer->setup(context, run.referencingRenderObject(), targetType)) {                        // Spec: Any properties specified on a text elements which represents a length, such as the                        // 'stroke-width' property, might produce surprising results since the length value will be                        // processed in the coordinate system of the glyph. (TODO: What other lengths? miter-limit? dash-offset?)                        if (targetType == ApplyToStrokeTargetType && scale != 0.0f)                            context->setStrokeThickness(context->strokeThickness() / scale);                        activePaintServer->renderPath(context, run.referencingRenderObject(), targetType);                        activePaintServer->teardown(context, run.referencingRenderObject(), targetType);                    }                    context->restore();                }                if (isVerticalText)                    currentPoint.move(0.0f, identifier.verticalAdvanceY * scale);                else                    currentPoint.move(identifier.horizontalAdvanceX * scale, 0.0f);            } else {                // Handle system font fallback                FontDescription fontDescription(m_fontDescription);                fontDescription.setFamily(FontFamily());                Font font(fontDescription, 0, 0); // spacing handled by SVG text code.                font.update(fontSelector());                TextRun fallbackCharacterRun(run);                fallbackCharacterRun.setText(&data.fallbackCharacters[run.rtl() ? data.fallbackCharacters.size() - fallbackCharacterIndex - 1 : fallbackCharacterIndex], 1);                font.drawText(context, fallbackCharacterRun, currentPoint);                if (isVerticalText)                    currentPoint.move(0.0f, font.floatWidth(fallbackCharacterRun));                else                    currentPoint.move(font.floatWidth(fallbackCharacterRun), 0.0f);                fallbackCharacterIndex++;            }        }    }}FloatRect Font::selectionRectForTextUsingSVGFont(const TextRun& run, const IntPoint& point, int height, int from, int to) const{    int charsConsumed;    String glyphName;    return FloatRect(point.x() + floatWidthOfSubStringUsingSVGFont(this, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed, glyphName),                     point.y(), floatWidthOfSubStringUsingSVGFont(this, run, 0, from, to, charsConsumed, glyphName), height);}int Font::offsetForPositionForTextUsingSVGFont(const TextRun&, int, bool) const{    // TODO: Fix text selection when HTML text is drawn using a SVG Font    // We need to integrate the SVG text selection code in the offsetForPosition() framework.    // This will also fix a major issue, that SVG Text code can't select arabic strings properly.    return 0;}}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -