cssstyleselector.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,879 行 · 第 1/5 页
CPP
1,879 行
void CSSStyleSelector::computeFontSizesFor(QPaintDeviceMetrics* paintDeviceMetrics, int zoomFactor, QValueVector<int>& fontSizes, bool isFixed){#ifdef APPLE_CHANGES // We don't want to scale the settings by the dpi. const float toPix = 1;#else Q_UNUSED( isFixed ); // ### get rid of float / double float toPix = paintDeviceMetrics->logicalDpiY()/72.; if (toPix < 96./72.) toPix = 96./72.;#endif // ######### fix isFixed code again. fontSizes.resize( MAXFONTSIZES ); float scale = 1.0; static const float fontFactors[] = {3./5., 3./4., 8./9., 1., 6./5., 3./2., 2., 3.}; static const float smallFontFactors[] = {3./4., 5./6., 8./9., 1., 6./5., 3./2., 2., 3.}; float mediumFontSize, minFontSize, factor; if (!khtml::printpainter) { scale *= zoomFactor / 100.0;#ifdef APPLE_CHANGES if (isFixed) mediumFontSize = settings->mediumFixedFontSize() * toPix; else#endif mediumFontSize = settings->mediumFontSize() * toPix; minFontSize = settings->minFontSize() * toPix; } else { // ## depending on something / configurable ? mediumFontSize = 12; minFontSize = 6; } const float* factors = scale*mediumFontSize >= 12.5 ? fontFactors : smallFontFactors; for ( int i = 0; i < MAXFONTSIZES; i++ ) { factor = scale*factors[i]; fontSizes[i] = int(KMAX( mediumFontSize*factor +.5f, minFontSize)); //kdDebug( 6080 ) << "index: " << i << " factor: " << factors[i] << " font pix size: " << int(KMAX( mediumFontSize*factor +.5f, minFontSize)) << endl; }}#undef MAXFONTSIZESstatic inline void bubbleSort( CSSOrderedProperty **b, CSSOrderedProperty **e ){ while( b < e ) { bool swapped = false; CSSOrderedProperty **y = e+1; CSSOrderedProperty **x = e; CSSOrderedProperty **swappedPos = 0; do { if ( !((**(--x)) < (**(--y))) ) { swapped = true; swappedPos = x; CSSOrderedProperty *tmp = *y; *y = *x; *x = tmp; } } while( x != b ); if ( !swapped ) break; b = swappedPos + 1; }}RenderStyle *CSSStyleSelector::styleForElement(ElementImpl *e){ if (!e->getDocument()->haveStylesheetsLoaded() || !e->getDocument()->view()) { if (!styleNotYetAvailable) { styleNotYetAvailable = new RenderStyle(); styleNotYetAvailable->setDisplay(NONE); styleNotYetAvailable->ref(); } return styleNotYetAvailable; } // set some variables we will need pseudoState = PseudoUnknown; element = e; parentNode = e->parentNode(); parentStyle = ( parentNode && parentNode->renderer()) ? parentNode->renderer()->style() : 0; view = element->getDocument()->view(); part = view->part(); settings = part->settings(); paintDeviceMetrics = element->getDocument()->paintDeviceMetrics(); style = new RenderStyle(); if( parentStyle ) style->inheritFrom( parentStyle ); else parentStyle = style; unsigned int numPropsToApply = 0; unsigned int numPseudoProps = 0; // try to sort out most style rules as early as possible. Q_UINT16 cssTagId = localNamePart(element->id()); int smatch = 0; int schecked = 0; for ( unsigned int i = 0; i < selectors_size; i++ ) { Q_UINT16 tag = localNamePart(selectors[i]->tag); if ( cssTagId == tag || tag == anyLocalName ) { ++schecked; checkSelector( i, e ); if ( selectorCache[i].state == Applies ) { ++smatch;// qDebug("adding property" ); for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 ) for ( unsigned int j = 0; j < (unsigned int )selectorCache[i].props[p+1]; ++j ) { if (numPropsToApply >= propsToApplySize ) { propsToApplySize *= 2; propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) ); } propsToApply[numPropsToApply++] = properties[selectorCache[i].props[p]+j]; } } else if ( selectorCache[i].state == AppliesPseudo ) { for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 ) for ( unsigned int j = 0; j < (unsigned int) selectorCache[i].props[p+1]; ++j ) { if (numPseudoProps >= pseudoPropsSize ) { pseudoPropsSize *= 2; pseudoProps = (CSSOrderedProperty **)realloc( pseudoProps, pseudoPropsSize*sizeof( CSSOrderedProperty * ) ); } pseudoProps[numPseudoProps++] = properties[selectorCache[i].props[p]+j]; properties[selectorCache[i].props[p]+j]->pseudoId = (RenderStyle::PseudoId) selectors[i]->pseudoId; } } } else selectorCache[i].state = Invalid; } // inline style declarations, after all others. non css hints // count as author rules, and come before all other style sheets, see hack in append() numPropsToApply = addInlineDeclarations( e, e->m_styleDecls, numPropsToApply );// qDebug( "styleForElement( %s )", e->tagName().string().latin1() );// qDebug( "%d selectors, %d checked, %d match, %d properties ( of %d )",// selectors_size, schecked, smatch, numPropsToApply, properties_size ); bubbleSort( propsToApply, propsToApply+numPropsToApply-1 ); bubbleSort( pseudoProps, pseudoProps+numPseudoProps-1 ); // we can't apply style rules without a view() and a part. This // tends to happen on delayed destruction of widget Renderobjects if ( part ) { fontDirty = false; if (numPropsToApply ) { CSSStyleSelector::style = style; for (unsigned int i = 0; i < numPropsToApply; ++i) { if ( fontDirty && propsToApply[i]->priority >= (1 << 30) ) { // we are past the font properties, time to update to the // correct font#ifdef APPLE_CHANGES checkForGenericFamilyChange(style, parentStyle);#endif CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics ); fontDirty = false; } DOM::CSSProperty *prop = propsToApply[i]->prop;// if (prop->m_id == CSS_PROP__KONQ_USER_INPUT) kdDebug(6080) << "El: "<<e->nodeName().string() << " user-input: "<<((CSSPrimitiveValueImpl *)prop->value())->getIdent() << endl;// if (prop->m_id == CSS_PROP_TEXT_TRANSFORM) kdDebug(6080) << "El: "<<e->nodeName().string() << endl; applyRule( prop->m_id, prop->value() ); } if ( fontDirty ) {#ifdef APPLE_CHANGES checkForGenericFamilyChange(style, parentStyle);#endif CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics ); } } // Clean up our style object's display and text decorations (among other fixups). adjustRenderStyle(style, e); if ( numPseudoProps ) { fontDirty = false; //qDebug("%d applying %d pseudo props", e->cssTagId(), pseudoProps->count() ); for (unsigned int i = 0; i < numPseudoProps; ++i) { if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) { // we are past the font properties, time to update to the // correct font //We have to do this for all pseudo styles RenderStyle *pseudoStyle = style->pseudoStyle; while ( pseudoStyle ) { pseudoStyle->htmlFont().update( paintDeviceMetrics ); pseudoStyle = pseudoStyle->pseudoStyle; } fontDirty = false; } RenderStyle *pseudoStyle; pseudoStyle = style->getPseudoStyle(pseudoProps[i]->pseudoId); if (!pseudoStyle) { pseudoStyle = style->addPseudoStyle(pseudoProps[i]->pseudoId); if (pseudoStyle) pseudoStyle->inheritFrom( style ); } RenderStyle* oldStyle = style; RenderStyle* oldParentStyle = parentStyle; parentStyle = style; style = pseudoStyle; if ( pseudoStyle ) { DOM::CSSProperty *prop = pseudoProps[i]->prop; applyRule( prop->m_id, prop->value() ); } style = oldStyle; parentStyle = oldParentStyle; } if ( fontDirty ) { RenderStyle *pseudoStyle = style->pseudoStyle; while ( pseudoStyle ) { pseudoStyle->htmlFont().update( paintDeviceMetrics ); pseudoStyle = pseudoStyle->pseudoStyle; } } } } // Now adjust all our pseudo-styles. RenderStyle *pseudoStyle = style->pseudoStyle; while (pseudoStyle) { adjustRenderStyle(pseudoStyle, 0); pseudoStyle = pseudoStyle->pseudoStyle; } // Now return the style. return style;}void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e){ // Cache our original display. style->setOriginalDisplay(style->display()); if (style->display() != NONE) { // If we have a <td> that specifies a float property, in quirks mode we just drop the float // property. // Sites also commonly use display:inline/block on <td>s and <table>s. In quirks mode we force // these tags to retain their display types. if (!strictParsing && e) { if (e->id() == ID_TD) { style->setDisplay(TABLE_CELL); style->setFloating(FNONE); }// else if (e->id() == ID_TABLE)// style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE); } // Table headers with a text-align of auto will change the text-align to center. if (e && e->id() == ID_TH && style->textAlign() == TAAUTO) style->setTextAlign(CENTER); // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to // position or float an inline, compact, or run-in. Cache the original display, since it // may be needed for positioned elements that have to compute their static normal flow // positions. We also force inline-level roots to be block-level. if (style->display() != BLOCK && style->display() != TABLE /*&& style->display() != BOX*/ && (style->position() == ABSOLUTE || style->position() == FIXED || style->floating() != FNONE || (e && e->getDocument()->documentElement() == e))) { if (style->display() == INLINE_TABLE) style->setDisplay(TABLE);// else if (style->display() == INLINE_BOX)// style->setDisplay(BOX); else if (style->display() == LIST_ITEM) { // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk, // but only in quirks mode. if (!strictParsing && style->floating() != FNONE) style->setDisplay(BLOCK); } else style->setDisplay(BLOCK); } // After performing the display mutation, check table rows. We do not honor position:relative on // table rows. This has been established in CSS2.1 (and caused a crash in containingBlock() on // some sites). // Likewise, disallow relative positioning on table sections. if ( style->position() == RELATIVE && (style->display() > INLINE_TABLE && style->display() < TABLE_COLUMN_GROUP) ) style->setPosition(STATIC); } // Frames and framesets never honor position:relative or position:absolute. This is necessary to // fix a crash where a site tries to position these objects. if ( e ) { // ignore display: none for <frame> if ( e->id() == ID_FRAME ) { style->setPosition( STATIC ); style->setDisplay( BLOCK ); } else if ( e->id() == ID_FRAMESET ) { style->setPosition( STATIC ); } } // Finally update our text decorations in effect, but don't allow text-decoration to percolate through // tables, inline blocks, inline tables, or run-ins. if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN || style->display() == INLINE_BLOCK /*|| style->display() == INLINE_BOX*/) style->setTextDecorationsInEffect(style->textDecoration()); else style->addToTextDecorationsInEffect(style->textDecoration()); // Cull out any useless layers and also repeat patterns into additional layers. style->adjustBackgroundLayers(); // Only use slow repaints if we actually have a background image. // FIXME: We only need to invalidate the fixed regions when scrolling. It's total overkill to // prevent the entire view from blitting on a scroll. if (style->hasFixedBackgroundImage() && view) view->useSlowRepaints();}unsigned int CSSStyleSelector::addInlineDeclarations(DOM::ElementImpl* e, DOM::CSSStyleDeclarationImpl *decl, unsigned int numProps){ CSSStyleDeclarationImpl* addDecls = 0;#ifdef APPLE_CHANGES if (e->id() == ID_TD || e->id() == ID_TH) // For now only TableCellElement implements the addDecls = e->getAdditionalStyleDecls(); // virtual function for shared cell rules.#else Q_UNUSED( e );#endif if (!decl && !addDecls) return numProps; QPtrList<CSSProperty>* values = decl ? decl->values() : 0; QPtrList<CSSProperty>* addValues = addDecls ? addDecls->values() : 0; if (!values && !addValues) return numProps; int firstLen = values ? values->count() : 0; int secondLen = addValues ? addValues->count() : 0; int totalLen = firstLen + secondLen; if (inlineProps.size() < (uint)totalLen) inlineProps.resize(totalLen + 1); if (numProps + totalLen >= propsToApplySize ) { propsToApplySize += propsToApplySize; propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) ); } CSSOrderedProperty *array = (CSSOrderedProperty *)inlineProps.data(); for(int i = 0; i < totalLen; i++) { if (i == firstLen) values = addValues; CSSProperty *prop = values->at(i >= firstLen ? i - firstLen : i); Source source = Inline; if( prop->m_bImportant ) source = InlineImportant; if( prop->nonCSSHint ) source = NonCSSHint; bool first; // give special priority to font-xxx, color properties switch(prop->m_id) { case CSS_PROP_FONT_STYLE: case CSS_PROP_FONT_SIZE: case CSS_PROP_FONT_WEIGHT: case CSS_PROP_FONT_FAMILY: case CSS_PROP_FONT: case CSS_PROP_COLOR:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?