📄 cssparser.cpp
字号:
break; value = valueList->next(); } if ( !value ) goto invalid; // set undefined values to default if ( !font->style ) font->style = new CSSPrimitiveValueImpl( CSS_VAL_NORMAL ); if ( !font->variant ) font->variant = new CSSPrimitiveValueImpl( CSS_VAL_NORMAL ); if ( !font->weight ) font->weight = new CSSPrimitiveValueImpl( CSS_VAL_NORMAL );// kdDebug( 6080 ) << " got style, variant and weight current=" << valueList->currentValue << endl; // now a font size _must_ come // <absolute-size> | <relative-size> | <length> | <percentage> | inherit if ( value->id >= CSS_VAL_XX_SMALL && value->id <= CSS_VAL_LARGER ) font->size = new CSSPrimitiveValueImpl( value->id ); else if ( validUnit( value, FLength|FPercent, strict ) ) { font->size = new CSSPrimitiveValueImpl( value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit ); } value = valueList->next(); if ( !font->size || !value ) goto invalid; // kdDebug( 6080 ) << " got size" << endl; if ( value->unit == Value::Operator && value->iValue == '/' ) { // line-height value = valueList->next(); if ( !value ) goto invalid; if ( value->id == CSS_VAL_NORMAL ) { // default value, nothing to do } else if ( validUnit( value, FNumber|FLength|FPercent, strict ) ) { font->lineHeight = new CSSPrimitiveValueImpl( value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit ); } else { goto invalid; } value = valueList->next(); if ( !value ) goto invalid; } if (!font->lineHeight) font->lineHeight = new CSSPrimitiveValueImpl( CSS_VAL_NORMAL );// kdDebug( 6080 ) << " got line height current=" << valueList->currentValue << endl; // font family must come now font->family = parseFontFamily(); if ( valueList->current() || !font->family ) goto invalid;// kdDebug( 6080 ) << " got family, parsing ok!" << endl; addProperty( CSS_PROP_FONT, font, important ); return true; invalid:// kdDebug(6080) << " -> invalid" << endl; delete font; return false;}CSSValueListImpl *CSSParser::parseFontFamily(){// kdDebug( 6080 ) << "CSSParser::parseFontFamily current=" << valueList->currentValue << endl; CSSValueListImpl *list = new CSSValueListImpl; Value *value = valueList->current(); FontFamilyValueImpl* currFamily = 0; while ( value ) {// kdDebug( 6080 ) << "got value " << value->id << " / "// << (value->unit == CSSPrimitiveValue::CSS_STRING ||// value->unit == CSSPrimitiveValue::CSS_IDENT ? qString( value->string ) : QString::null )// << endl; Value* nextValue = valueList->next(); bool nextValBreaksFont = !nextValue || (nextValue->unit == Value::Operator && nextValue->iValue == ','); bool nextValIsFontName = nextValue && ((nextValue->id >= CSS_VAL_SERIF && nextValue->id <= CSS_VAL__KHTML_BODY) || (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT)); if (value->id >= CSS_VAL_SERIF && value->id <= CSS_VAL__KHTML_BODY) { if (currFamily) { currFamily->parsedFontName += ' '; currFamily->parsedFontName += qString(value->string); } else if (nextValBreaksFont || !nextValIsFontName) list->append(new CSSPrimitiveValueImpl(value->id)); else list->append(currFamily = new FontFamilyValueImpl(qString(value->string))); } else if (value->unit == CSSPrimitiveValue::CSS_STRING) { // Strings never share in a family name. currFamily = 0; list->append(new FontFamilyValueImpl(qString( value->string))); } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) { if (currFamily) { currFamily->parsedFontName += ' '; currFamily->parsedFontName += qString(value->string); } else if (nextValBreaksFont || !nextValIsFontName) list->append(new FontFamilyValueImpl(qString( value->string))); else list->append(currFamily = new FontFamilyValueImpl(qString(value->string))); } else {// kdDebug( 6080 ) << "invalid family part" << endl; break; } if (!nextValue) break; if (nextValBreaksFont) { value = valueList->next(); currFamily = 0; } else if (nextValIsFontName) value = nextValue; else break; } if ( !list->length() ) { delete list; list = 0; } return list;}bool CSSParser::parseColor(const QString &name, QRgb& rgb){ int len = name.length(); if ( !len ) return false; bool ok; if ( len == 3 || len == 6 ) { int val = name.toInt(&ok, 16); if ( ok ) { if (len == 6) { rgb = (0xff << 24) | val; return true; } else if ( len == 3 ) { // #abc converts to #aabbcc according to the specs rgb = (0xff << 24) | (val&0xf00)<<12 | (val&0xf00)<<8 | (val&0xf0)<<8 | (val&0xf0)<<4 | (val&0xf)<<4 | (val&0xf); return true; } } } // try a little harder QColor tc; tc.setNamedColor(name.lower()); if (tc.isValid()) { rgb = tc.rgb(); return true; } return false;}CSSPrimitiveValueImpl *CSSParser::parseColor(){ return parseColorFromValue(valueList->current());}CSSPrimitiveValueImpl *CSSParser::parseColorFromValue(Value* value){ QRgb c = khtml::transparentColor; if ( !strict && value->unit == CSSPrimitiveValue::CSS_NUMBER && value->fValue >= 0. && value->fValue < 1000000. ) { QString str; str.sprintf( "%06d", (int)(value->fValue+.5) ); if (!CSSParser::parseColor( str, c )) return 0; } else if ( value->unit == CSSPrimitiveValue::CSS_RGBCOLOR || value->unit == CSSPrimitiveValue::CSS_IDENT || value->unit == CSSPrimitiveValue::CSS_DIMENSION ) { if (!CSSParser::parseColor( qString( value->string ), c)) return 0; } else if ( value->unit == Value::Function && value->function->args != 0 && value->function->args->numValues == 5 /* rgb + two commas */ && qString( value->function->name ).lower() == "rgb(" ) { ValueList *args = value->function->args; Value *v = args->current(); if ( !validUnit( v, FInteger|FPercent, true ) ) return 0; int r = (int) ( v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256./100. : 1.) ); v = args->next(); if ( v->unit != Value::Operator && v->iValue != ',' ) return 0; v = args->next(); if ( !validUnit( v, FInteger|FPercent, true ) ) return 0; int g = (int) ( v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256./100. : 1.) ); v = args->next(); if ( v->unit != Value::Operator && v->iValue != ',' ) return 0; v = args->next(); if ( !validUnit( v, FInteger|FPercent, true ) ) return 0; int b = (int) ( v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256./100. : 1.) ); r = QMAX( 0, QMIN( 255, r ) ); g = QMAX( 0, QMIN( 255, g ) ); b = QMAX( 0, QMIN( 255, b ) ); c = qRgb( r, g, b ); } else if ( value->unit == Value::Function && value->function->args != 0 && value->function->args->numValues == 7 /* rgba + three commas */ && qString( value->function->name ).lower() == "rgba(" ) { ValueList *args = value->function->args; Value *v = args->current(); if ( !validUnit( v, FInteger|FPercent, true ) ) return 0; int r = (int) ( v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256./100. : 1.) ); v = args->next(); if ( v->unit != Value::Operator && v->iValue != ',' ) return 0; v = args->next(); if ( !validUnit( v, FInteger|FPercent, true ) ) return 0; int g = (int) ( v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256./100. : 1.) ); v = args->next(); if ( v->unit != Value::Operator && v->iValue != ',' ) return 0; v = args->next(); if ( !validUnit( v, FInteger|FPercent, true ) ) return 0; int b = (int) ( v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256./100. : 1.) ); v = args->next(); if ( v->unit != Value::Operator && v->iValue != ',' ) return 0; v = args->next(); if ( !validUnit( v, FNumber, true ) ) return 0; r = QMAX( 0, QMIN( 255, r ) ); g = QMAX( 0, QMIN( 255, g ) ); b = QMAX( 0, QMIN( 255, b ) ); int a = (int)(QMAX( 0, QMIN( 1.0f, v->fValue ) ) * 255); c = qRgba( r, g, b, a ); } else return 0; return new CSSPrimitiveValueImpl(c);}// This class tracks parsing state for shadow values. If it goes out of scope (e.g., due to an early return)// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.struct ShadowParseContext { ShadowParseContext() :values(0), x(0), y(0), blur(0), color(0), allowX(true), allowY(false), allowBlur(false), allowColor(true), allowBreak(true) {} ~ShadowParseContext() { if (!allowBreak) { delete values; delete x; delete y; delete blur; delete color; } } bool allowLength() { return allowX || allowY || allowBlur; } bool failed() { return allowBreak = false; } void commitValue() { // Handle the ,, case gracefully by doing nothing. if (x || y || blur || color) { if (!values) values = new CSSValueListImpl(); // Construct the current shadow value and add it to the list. values->append(new ShadowValueImpl(x, y, blur, color)); } // Now reset for the next shadow value. x = y = blur = color = 0; allowX = allowColor = allowBreak = true; allowY = allowBlur = false; } void commitLength(Value* v) { CSSPrimitiveValueImpl* val = new CSSPrimitiveValueImpl(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit); if (allowX) { x = val; allowX = false; allowY = true; allowColor = false; allowBreak = false; } else if (allowY) { y = val; allowY = false; allowBlur = true; allowColor = true; allowBreak = true; } else if (allowBlur) { blur = val; allowBlur = false; } } void commitColor(CSSPrimitiveValueImpl* val) { color = val; allowColor = false; if (allowX) allowBreak = false; else allowBlur = false; } CSSValueListImpl* values; CSSPrimitiveValueImpl* x; CSSPrimitiveValueImpl* y; CSSPrimitiveValueImpl* blur; CSSPrimitiveValueImpl* color; bool allowX; bool allowY; bool allowBlur; bool allowColor; bool allowBreak;};bool CSSParser::parseShadow(int propId, bool important){ ShadowParseContext context; Value* val; while ((val = valueList->current())) { // Check for a comma break first. if (val->unit == Value::Operator) { if (val->iValue != ',' || !context.allowBreak) // Other operators aren't legal or we aren't done with the current shadow // value. Treat as invalid. return context.failed(); // The value is good. Commit it. context.commitValue(); } // Check to see if we're a length. else if (validUnit(val, FLength, true)) { // We required a length and didn't get one. Invalid. if (!context.allowLength()) return context.failed(); // A length is allowed here. Construct the value and add it. context.commitLength(val); } else { // The only other type of value that's ok is a color value. CSSPrimitiveValueImpl* parsedColor = 0; bool isColor = (val->id >= CSS_VAL_AQUA && val->id <= CSS_VAL_WINDOWTEXT || val->id == CSS_VAL_MENU || (val->id >= CSS_VAL_GREY && val->id <= CSS_VAL__KHTML_TEXT && !strict)); if (isColor) { if (!context.allowColor) return context.failed(); parsedColor = new CSSPrimitiveValueImpl(val->id); } if (!parsedColor) // It's not built-in. Try to parse it as a color. parsedColor = parseColorFromValue(val); if (!parsedColor || !context.allowColor) return co
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -