📄 qcssparser.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qcssparser_p.h"#include <qdebug.h>#include <qcolor.h>#include <qfont.h>#include <qfileinfo.h>#include <qfontmetrics.h>#include <qbrush.h>#include "qcssscanner.cpp"using namespace QCss;const char *Scanner::tokenName(TokenType t){ switch (t) { case NONE: return "NONE"; case S: return "S"; case CDO: return "CDO"; case CDC: return "CDC"; case INCLUDES: return "INCLUDES"; case DASHMATCH: return "DASHMATCH"; case LBRACE: return "LBRACE"; case PLUS: return "PLUS"; case GREATER: return "GREATER"; case COMMA: return "COMMA"; case STRING: return "STRING"; case INVALID: return "INVALID"; case IDENT: return "IDENT"; case HASH: return "HASH"; case ATKEYWORD_SYM: return "ATKEYWORD_SYM"; case EXCLAMATION_SYM: return "EXCLAMATION_SYM"; case LENGTH: return "LENGTH"; case PERCENTAGE: return "PERCENTAGE"; case NUMBER: return "NUMBER"; case FUNCTION: return "FUNCTION"; case COLON: return "COLON"; case SEMICOLON: return "SEMICOLON"; case RBRACE: return "RBRACE"; case SLASH: return "SLASH"; case MINUS: return "MINUS"; case DOT: return "DOT"; case STAR: return "STAR"; case LBRACKET: return "LBRACKET"; case RBRACKET: return "RBRACKET"; case EQUAL: return "EQUAL"; case LPAREN: return "LPAREN"; case RPAREN: return "RPAREN"; case OR: return "OR"; } return "";}struct QCssKnownValue{ const char *name; int id;};static const QCssKnownValue properties[NumProperties - 1] = { { "-qt-background-role", QtBackgroundRole }, { "-qt-block-indent", QtBlockIndent }, { "-qt-list-indent", QtListIndent }, { "-qt-paragraph-type", QtParagraphType }, { "-qt-style-features", QtStyleFeatures }, { "-qt-table-type", QtTableType }, { "-qt-user-state", QtUserState }, { "alternate-background-color", QtAlternateBackground }, { "background", Background }, { "background-attachment", BackgroundAttachment }, { "background-clip", BackgroundClip }, { "background-color", BackgroundColor }, { "background-image", BackgroundImage }, { "background-origin", BackgroundOrigin }, { "background-position", BackgroundPosition }, { "background-repeat", BackgroundRepeat }, { "border", Border }, { "border-bottom", BorderBottom }, { "border-bottom-color", BorderBottomColor }, { "border-bottom-left-radius", BorderBottomLeftRadius }, { "border-bottom-right-radius", BorderBottomRightRadius }, { "border-bottom-style", BorderBottomStyle }, { "border-bottom-width", BorderBottomWidth }, { "border-color", BorderColor }, { "border-image", BorderImage }, { "border-left", BorderLeft }, { "border-left-color", BorderLeftColor }, { "border-left-style", BorderLeftStyle }, { "border-left-width", BorderLeftWidth }, { "border-radius", BorderRadius }, { "border-right", BorderRight }, { "border-right-color", BorderRightColor }, { "border-right-style", BorderRightStyle }, { "border-right-width", BorderRightWidth }, { "border-style", BorderStyles }, { "border-top", BorderTop }, { "border-top-color", BorderTopColor }, { "border-top-left-radius", BorderTopLeftRadius }, { "border-top-right-radius", BorderTopRightRadius }, { "border-top-style", BorderTopStyle }, { "border-top-width", BorderTopWidth }, { "border-width", BorderWidth }, { "bottom", Bottom }, { "color", Color }, { "float", Float }, { "font", Font }, { "font-family", FontFamily }, { "font-size", FontSize }, { "font-style", FontStyle }, { "font-weight", FontWeight }, { "height", Height }, { "image", QtImage }, { "image-position", QtImageAlignment }, { "left", Left }, { "list-style", ListStyle }, { "list-style-type", ListStyleType }, { "margin" , Margin }, { "margin-bottom", MarginBottom }, { "margin-left", MarginLeft }, { "margin-right", MarginRight }, { "margin-top", MarginTop }, { "max-height", MaximumHeight }, { "max-width", MaximumWidth }, { "min-height", MinimumHeight }, { "min-width", MinimumWidth }, { "padding", Padding }, { "padding-bottom", PaddingBottom }, { "padding-left", PaddingLeft }, { "padding-right", PaddingRight }, { "padding-top", PaddingTop }, { "page-break-after", PageBreakAfter }, { "page-break-before", PageBreakBefore }, { "position", Position }, { "right", Right }, { "selection-background-color", QtSelectionBackground }, { "selection-color", QtSelectionForeground }, { "spacing", QtSpacing }, { "subcontrol-origin", QtOrigin }, { "subcontrol-position", QtPosition }, { "text-align", TextAlignment }, { "text-decoration", TextDecoration }, { "text-indent", TextIndent }, { "text-underline-style", TextUnderlineStyle }, { "top", Top }, { "vertical-align", VerticalAlignment }, { "white-space", Whitespace }, { "width", Width }};static const QCssKnownValue values[NumKnownValues - 1] = { { "alternate-base", Value_AlternateBase }, { "always", Value_Always }, { "auto", Value_Auto }, { "base", Value_Base }, { "bold", Value_Bold }, { "bottom", Value_Bottom }, { "bright-text", Value_BrightText }, { "button", Value_Button }, { "button-text", Value_ButtonText }, { "center", Value_Center }, { "circle", Value_Circle }, { "dark", Value_Dark }, { "dashed", Value_Dashed }, { "decimal", Value_Decimal }, { "disc", Value_Disc }, { "dot-dash", Value_DotDash }, { "dot-dot-dash", Value_DotDotDash }, { "dotted", Value_Dotted }, { "double", Value_Double }, { "groove", Value_Groove }, { "highlight", Value_Highlight }, { "highlighted-text", Value_HighlightedText }, { "inset", Value_Inset }, { "italic", Value_Italic }, { "large", Value_Large }, { "left", Value_Left }, { "light", Value_Light }, { "line-through", Value_LineThrough }, { "link", Value_Link }, { "link-visited", Value_LinkVisited }, { "lower-alpha", Value_LowerAlpha }, { "medium", Value_Medium }, { "mid", Value_Mid }, { "middle", Value_Middle }, { "midlight", Value_Midlight }, { "native", Value_Native }, { "none", Value_None }, { "normal", Value_Normal }, { "nowrap", Value_NoWrap }, { "oblique", Value_Oblique }, { "outset", Value_Outset }, { "overline", Value_Overline }, { "pre", Value_Pre }, { "pre-wrap", Value_PreWrap }, { "ridge", Value_Ridge }, { "right", Value_Right }, { "shadow", Value_Shadow }, { "small" , Value_Small }, { "solid", Value_Solid }, { "square", Value_Square }, { "sub", Value_Sub }, { "super", Value_Super }, { "text", Value_Text }, { "top", Value_Top }, { "transparent", Value_Transparent }, { "underline", Value_Underline }, { "upper-alpha", Value_UpperAlpha }, { "wave", Value_Wave }, { "window", Value_Window }, { "window-text", Value_WindowText }, { "x-large", Value_XLarge }, { "xx-large", Value_XXLarge }};static const QCssKnownValue pseudos[NumPseudos - 1] = { { "adjoins-item", PseudoClass_Item }, { "bottom", PseudoClass_Bottom }, { "checked", PseudoClass_Checked }, { "closed", PseudoClass_Closed }, { "default", PseudoClass_Default }, { "disabled", PseudoClass_Disabled }, { "editable", PseudoClass_Editable }, { "enabled", PseudoClass_Enabled }, { "exclusive", PseudoClass_Exclusive }, { "first", PseudoClass_First }, { "flat", PseudoClass_Flat }, { "focus", PseudoClass_Focus }, { "has-children", PseudoClass_Children }, { "has-siblings", PseudoClass_Sibling }, { "horizontal", PseudoClass_Horizontal }, { "hover", PseudoClass_Hover }, { "indeterminate" , PseudoClass_Indeterminate }, { "last", PseudoClass_Last }, { "left", PseudoClass_Left }, { "middle", PseudoClass_Middle }, { "next-selected", PseudoClass_NextSelected }, { "no-frame", PseudoClass_Frameless }, { "non-exclusive", PseudoClass_NonExclusive }, { "off", PseudoClass_Unchecked }, { "on", PseudoClass_Checked }, { "only-one", PseudoClass_OnlyOne }, { "open", PseudoClass_Open }, { "pressed", PseudoClass_Pressed }, { "previous-selected", PseudoClass_PreviousSelected }, { "read-only", PseudoClass_ReadOnly }, { "right", PseudoClass_Right }, { "selected", PseudoClass_Selected }, { "top", PseudoClass_Top }, { "unchecked" , PseudoClass_Unchecked }, { "vertical", PseudoClass_Vertical },};static const QCssKnownValue origins[NumKnownOrigins - 1] = { { "border", Origin_Border }, { "content", Origin_Content }, { "margin", Origin_Margin }, // not in css { "padding", Origin_Padding }};static const QCssKnownValue repeats[NumKnownRepeats - 1] = { { "no-repeat", Repeat_None }, { "repeat-x", Repeat_X }, { "repeat-xy", Repeat_XY }, { "repeat-y", Repeat_Y }};static const QCssKnownValue tileModes[NumKnownTileModes - 1] = { { "repeat", TileMode_Repeat }, { "round", TileMode_Round }, { "stretch", TileMode_Stretch },};static const QCssKnownValue positions[NumKnownPositionModes - 1] = { { "absolute", PositionMode_Absolute }, { "fixed", PositionMode_Fixed }, { "relative", PositionMode_Relative }, { "static", PositionMode_Static }};static const QCssKnownValue attachments[NumKnownAttachments - 1] = { { "fixed", Attachment_Fixed }, { "scroll", Attachment_Scroll }};static const QCssKnownValue styleFeatures[NumKnownStyleFeatures - 1] = { { "background-color", StyleFeature_BackgroundColor }, { "background-gradient", StyleFeature_BackgroundGradient }, { "none", StyleFeature_None }};static bool operator<(const QString &name, const QCssKnownValue &prop){ return QString::compare(name, QLatin1String(prop.name), Qt::CaseInsensitive) < 0;}static bool operator<(const QCssKnownValue &prop, const QString &name){ return QString::compare(QLatin1String(prop.name), name, Qt::CaseInsensitive) < 0;}static int findKnownValue(const QString &name, const QCssKnownValue *start, int numValues){ const QCssKnownValue *end = &start[numValues - 1]; const QCssKnownValue *prop = qBinaryFind(start, end, name); if (prop == end) return 0; return prop->id;}///////////////////////////////////////////////////////////////////////////////// Value ExtractorValueExtractor::ValueExtractor(const QVector<Declaration> &decls, const QPalette &pal): declarations(decls), adjustment(0), fontExtracted(false), pal(pal){}int ValueExtractor::lengthValue(const Value& v){ QString s = v.variant.toString(); QRegExp re(QLatin1String("(-?[\\d\\.]*)(px|em|ex)?"), Qt::CaseInsensitive); if (re.indexIn(s) == -1) return 0; QString real = re.cap(1); QString unit = re.cap(2); bool ok; qreal number = real.toDouble(&ok); if (!ok) return 0; QFontMetrics fm(f); if (unit.compare(QLatin1String("ex"), Qt::CaseInsensitive) == 0) return qRound(fm.xHeight() * number); else if (unit.compare(QLatin1String("em"), Qt::CaseInsensitive) == 0) return qRound(fm.height() * number); return qRound(number);}int ValueExtractor::lengthValue(const Declaration &decl){ if (decl.values.count() < 1) return 0; return lengthValue(decl.values.first());}void ValueExtractor::lengthValues(const Declaration &decl, int *m){ int i; for (i = 0; i < qMin(decl.values.count(), 4); i++) m[i] = lengthValue(decl.values[i]); if (i == 0) m[0] = m[1] = m[2] = m[3] = 0; else if (i == 1) m[3] = m[2] = m[1] = m[0]; else if (i == 2) m[2] = m[0], m[3] = m[1]; else if (i == 3) m[3] = m[1];}bool ValueExtractor::extractGeometry(int *w, int *h, int *minw, int *minh, int *maxw, int *maxh){ extractFont(); bool hit = false; for (int i = 0; i < declarations.count(); i++) { const Declaration &decl = declarations.at(i); switch (decl.propertyId) { case Width: *w = lengthValue(decl); break; case Height: *h = lengthValue(decl); break; case MinimumWidth: *minw = lengthValue(decl); break; case MinimumHeight: *minh = lengthValue(decl); break; case MaximumWidth: *maxw = lengthValue(decl); break; case MaximumHeight: *maxh = lengthValue(decl); break; default: continue; } hit = true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -