src/svg/qsvgstructure.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtSvg module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qsvgstructure_p.h"
       
    43 
       
    44 #ifndef QT_NO_SVG
       
    45 
       
    46 #include "qsvgnode_p.h"
       
    47 #include "qsvgstyle_p.h"
       
    48 #include "qsvgtinydocument_p.h"
       
    49 
       
    50 #include "qpainter.h"
       
    51 #include "qlocale.h"
       
    52 #include "qdebug.h"
       
    53 
       
    54 QT_BEGIN_NAMESPACE
       
    55 
       
    56 QSvgG::QSvgG(QSvgNode *parent)
       
    57     : QSvgStructureNode(parent)
       
    58 {
       
    59 
       
    60 }
       
    61 
       
    62 QSvgStructureNode::~QSvgStructureNode()
       
    63 {
       
    64     qDeleteAll(m_renderers);
       
    65 }
       
    66 
       
    67 void QSvgG::draw(QPainter *p, QSvgExtraStates &states)
       
    68 {
       
    69     QList<QSvgNode*>::iterator itr = m_renderers.begin();
       
    70     applyStyle(p, states);
       
    71 
       
    72     while (itr != m_renderers.end()) {
       
    73         QSvgNode *node = *itr;
       
    74         if ((node->isVisible()) && (node->displayMode() != QSvgNode::NoneMode))
       
    75             node->draw(p, states);
       
    76         ++itr;
       
    77     }
       
    78     revertStyle(p, states);
       
    79 }
       
    80 
       
    81 QSvgNode::Type QSvgG::type() const
       
    82 {
       
    83     return G;
       
    84 }
       
    85 
       
    86 QSvgStructureNode::QSvgStructureNode(QSvgNode *parent)
       
    87     :QSvgNode(parent)
       
    88 {
       
    89 
       
    90 }
       
    91 
       
    92 QSvgNode * QSvgStructureNode::scopeNode(const QString &id) const
       
    93 {
       
    94     QSvgTinyDocument *doc = document();
       
    95     return doc ? doc->namedNode(id) : 0;
       
    96 }
       
    97 
       
    98 void QSvgStructureNode::addChild(QSvgNode *child, const QString &id)
       
    99 {
       
   100     m_renderers.append(child);
       
   101 
       
   102     if (id.isEmpty())
       
   103         return; //we can't add it to scope without id
       
   104 
       
   105     QSvgTinyDocument *doc = document();
       
   106     if (doc)
       
   107         doc->addNamedNode(id, child);
       
   108 }
       
   109 
       
   110 QSvgDefs::QSvgDefs(QSvgNode *parent)
       
   111     : QSvgStructureNode(parent)
       
   112 {
       
   113 }
       
   114 
       
   115 void QSvgDefs::draw(QPainter *, QSvgExtraStates &)
       
   116 {
       
   117     //noop
       
   118 }
       
   119 
       
   120 QSvgNode::Type QSvgDefs::type() const
       
   121 {
       
   122     return DEFS;
       
   123 }
       
   124 
       
   125 /*
       
   126   Below is a lookup function based on the gperf output using the following set:
       
   127 
       
   128   http://www.w3.org/Graphics/SVG/feature/1.2/#SVG
       
   129   http://www.w3.org/Graphics/SVG/feature/1.2/#SVG-static
       
   130   http://www.w3.org/Graphics/SVG/feature/1.2/#CoreAttribute
       
   131   http://www.w3.org/Graphics/SVG/feature/1.2/#Structure
       
   132   http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessing
       
   133   http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessingAttribute
       
   134   http://www.w3.org/Graphics/SVG/feature/1.2/#Image
       
   135   http://www.w3.org/Graphics/SVG/feature/1.2/#Prefetch
       
   136   http://www.w3.org/Graphics/SVG/feature/1.2/#Shape
       
   137   http://www.w3.org/Graphics/SVG/feature/1.2/#Text
       
   138   http://www.w3.org/Graphics/SVG/feature/1.2/#PaintAttribute
       
   139   http://www.w3.org/Graphics/SVG/feature/1.2/#OpacityAttribute
       
   140   http://www.w3.org/Graphics/SVG/feature/1.2/#GraphicsAttribute
       
   141   http://www.w3.org/Graphics/SVG/feature/1.2/#Gradient
       
   142   http://www.w3.org/Graphics/SVG/feature/1.2/#SolidColor
       
   143   http://www.w3.org/Graphics/SVG/feature/1.2/#XlinkAttribute
       
   144   http://www.w3.org/Graphics/SVG/feature/1.2/#ExternalResourcesRequiredAttribute
       
   145   http://www.w3.org/Graphics/SVG/feature/1.2/#Font
       
   146   http://www.w3.org/Graphics/SVG/feature/1.2/#Hyperlinking
       
   147   http://www.w3.org/Graphics/SVG/feature/1.2/#Extensibility
       
   148 */
       
   149 
       
   150 // ----- begin of generated code -----
       
   151 
       
   152 /* C code produced by gperf version 3.0.2 */
       
   153 /* Command-line: gperf -c -L c svg  */
       
   154 /* Computed positions: -k'45-46' */
       
   155 
       
   156 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
       
   157       && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
       
   158       && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
       
   159       && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
       
   160       && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
       
   161       && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
       
   162       && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
       
   163       && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
       
   164       && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
       
   165       && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
       
   166       && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
       
   167       && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
       
   168       && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
       
   169       && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
       
   170       && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
       
   171       && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
       
   172       && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
       
   173       && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
       
   174       && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
       
   175       && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
       
   176       && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
       
   177       && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
       
   178       && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
       
   179 /* The character set is not based on ISO-646.  */
       
   180 #error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
       
   181 #endif
       
   182 
       
   183 enum {
       
   184     TOTAL_KEYWORDS = 20,
       
   185     MIN_WORD_LENGTH = 47,
       
   186     MAX_WORD_LENGTH = 78,
       
   187     MIN_HASH_VALUE = 48,
       
   188     MAX_HASH_VALUE = 88
       
   189 };
       
   190 /* maximum key range = 41, duplicates = 0 */
       
   191 
       
   192 inline static bool isSupportedSvgFeature(const QString &str)
       
   193 {
       
   194     static const unsigned char asso_values[] = {
       
   195         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   196         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   197         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   198         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   199         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   200         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   201         89, 89, 89, 89, 89, 89, 89,  0, 89,  5,
       
   202         15,  5,  0, 10, 89, 89, 89, 89, 89,  0,
       
   203         15, 89, 89,  0,  0, 89,  5, 89,  0, 89,
       
   204         89, 89, 89, 89, 89, 89, 89,  0, 89, 89,
       
   205         89,  0, 89, 89,  0, 89, 89, 89,  0,  5,
       
   206         89,  0,  0, 89,  5, 89,  0, 89, 89, 89,
       
   207         5,  0, 89, 89, 89, 89, 89, 89, 89, 89,
       
   208         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   209         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   210         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   211         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   212         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   213         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   214         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   215         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   216         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   217         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   218         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   219         89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
       
   220         89, 89, 89, 89, 89, 89
       
   221     };
       
   222 
       
   223     static const char * wordlist[] = {
       
   224         "", "", "", "", "", "", "", "", "",
       
   225         "", "", "", "", "", "", "", "", "",
       
   226         "", "", "", "", "", "", "", "", "",
       
   227         "", "", "", "", "", "", "", "", "",
       
   228         "", "", "", "", "", "", "", "", "",
       
   229         "", "", "",
       
   230         "http://www.w3.org/Graphics/SVG/feature/1.2/#Text",
       
   231         "http://www.w3.org/Graphics/SVG/feature/1.2/#Shape",
       
   232         "", "",
       
   233         "http://www.w3.org/Graphics/SVG/feature/1.2/#SVG",
       
   234         "http://www.w3.org/Graphics/SVG/feature/1.2/#Structure",
       
   235         "http://www.w3.org/Graphics/SVG/feature/1.2/#SolidColor",
       
   236         "",
       
   237         "http://www.w3.org/Graphics/SVG/feature/1.2/#Hyperlinking",
       
   238         "http://www.w3.org/Graphics/SVG/feature/1.2/#CoreAttribute",
       
   239         "http://www.w3.org/Graphics/SVG/feature/1.2/#XlinkAttribute",
       
   240         "http://www.w3.org/Graphics/SVG/feature/1.2/#SVG-static",
       
   241         "http://www.w3.org/Graphics/SVG/feature/1.2/#OpacityAttribute",
       
   242         "",
       
   243         "http://www.w3.org/Graphics/SVG/feature/1.2/#Gradient",
       
   244         "http://www.w3.org/Graphics/SVG/feature/1.2/#Font",
       
   245         "http://www.w3.org/Graphics/SVG/feature/1.2/#Image",
       
   246         "http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessing",
       
   247         "",
       
   248         "http://www.w3.org/Graphics/SVG/feature/1.2/#Extensibility",
       
   249         "", "", "",
       
   250         "http://www.w3.org/Graphics/SVG/feature/1.2/#GraphicsAttribute",
       
   251         "http://www.w3.org/Graphics/SVG/feature/1.2/#Prefetch",
       
   252         "http://www.w3.org/Graphics/SVG/feature/1.2/#PaintAttribute",
       
   253         "http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessingAttribute",
       
   254         "", "", "", "", "", "", "", "", "",
       
   255         "", "", "", "",
       
   256         "http://www.w3.org/Graphics/SVG/feature/1.2/#ExternalResourcesRequiredAttribute"
       
   257     };
       
   258 
       
   259     if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
       
   260         const int key = str.length()
       
   261                         + asso_values[str.at(45).unicode()]
       
   262                         + asso_values[str.at(44).unicode()];
       
   263         if (key <= MAX_HASH_VALUE && key >= 0)
       
   264             return str == QLatin1String(wordlist[key]);
       
   265     }
       
   266     return false;
       
   267 }
       
   268 
       
   269 // ----- end of generated code -----
       
   270 
       
   271 static inline bool isSupportedSvgExtension(const QString &)
       
   272 {
       
   273     return false;
       
   274 }
       
   275 
       
   276 
       
   277 QSvgSwitch::QSvgSwitch(QSvgNode *parent)
       
   278     : QSvgStructureNode(parent)
       
   279 {
       
   280     init();
       
   281 }
       
   282 
       
   283 void QSvgSwitch::draw(QPainter *p, QSvgExtraStates &states)
       
   284 {
       
   285     QList<QSvgNode*>::iterator itr = m_renderers.begin();
       
   286     applyStyle(p, states);
       
   287 
       
   288     while (itr != m_renderers.end()) {
       
   289         QSvgNode *node = *itr;
       
   290         if (node->isVisible() && (node->displayMode() != QSvgNode::NoneMode)) {
       
   291             const QStringList &features  = node->requiredFeatures();
       
   292             const QStringList &extensions = node->requiredExtensions();
       
   293             const QStringList &languages = node->requiredLanguages();
       
   294             const QStringList &formats = node->requiredFormats();
       
   295             const QStringList &fonts = node->requiredFonts();
       
   296 
       
   297             bool okToRender = true;
       
   298             if (!features.isEmpty()) {
       
   299                 QStringList::const_iterator sitr = features.constBegin();
       
   300                 for (; sitr != features.constEnd(); ++sitr) {
       
   301                     if (!isSupportedSvgFeature(*sitr)) {
       
   302                         okToRender = false;
       
   303                         break;
       
   304                     }
       
   305                 }
       
   306             }
       
   307 
       
   308             if (okToRender && !extensions.isEmpty()) {
       
   309                 QStringList::const_iterator sitr = extensions.constBegin();
       
   310                 for (; sitr != extensions.constEnd(); ++sitr) {
       
   311                     if (!isSupportedSvgExtension(*sitr)) {
       
   312                         okToRender = false;
       
   313                         break;
       
   314                     }
       
   315                 }
       
   316             }
       
   317 
       
   318             if (okToRender && !languages.isEmpty()) {
       
   319                 QStringList::const_iterator sitr = languages.constBegin();
       
   320                 okToRender = false;
       
   321                 for (; sitr != languages.constEnd(); ++sitr) {
       
   322                     if ((*sitr).startsWith(m_systemLanguagePrefix)) {
       
   323                         okToRender = true;
       
   324                         break;
       
   325                     }
       
   326                 }
       
   327             }
       
   328 
       
   329             if (okToRender && !formats.isEmpty()) {
       
   330                 okToRender = false;
       
   331             }
       
   332 
       
   333             if (okToRender && !fonts.isEmpty()) {
       
   334                 okToRender = false;
       
   335             }
       
   336 
       
   337             if (okToRender) {
       
   338                 node->draw(p, states);
       
   339                 break;
       
   340             }
       
   341         }
       
   342         ++itr;
       
   343     }
       
   344     revertStyle(p, states);
       
   345 }
       
   346 
       
   347 QSvgNode::Type QSvgSwitch::type() const
       
   348 {
       
   349     return SWITCH;
       
   350 }
       
   351 
       
   352 void QSvgSwitch::init()
       
   353 {
       
   354     QLocale locale;
       
   355     m_systemLanguage = locale.name().replace(QLatin1Char('_'), QLatin1Char('-'));
       
   356     int idx = m_systemLanguage.indexOf(QLatin1Char('-'));
       
   357     m_systemLanguagePrefix = m_systemLanguage.mid(0, idx);
       
   358 }
       
   359 
       
   360 QRectF QSvgStructureNode::bounds() const
       
   361 {
       
   362     if (m_bounds.isEmpty()) {
       
   363         foreach(QSvgNode *node, m_renderers) {
       
   364             m_bounds |= node->transformedBounds(QTransform());
       
   365         }
       
   366     }
       
   367 
       
   368     return m_bounds;
       
   369 }
       
   370 
       
   371 QSvgNode * QSvgStructureNode::previousSiblingNode(QSvgNode *n) const
       
   372 {
       
   373     QSvgNode *prev = 0;
       
   374     QList<QSvgNode*>::const_iterator itr = m_renderers.constBegin();
       
   375     while (itr != m_renderers.constEnd()) {
       
   376         QSvgNode *node = *itr;
       
   377         if (node == n)
       
   378             return prev;
       
   379         prev = node;
       
   380     }
       
   381     return prev;
       
   382 }
       
   383 
       
   384 QT_END_NAMESPACE
       
   385 
       
   386 #endif // QT_NO_SVG