LCOV - code coverage report
Current view: top level - sw/source/filter/html - parcss1.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 5 595 0.8 %
Date: 2012-08-25 Functions: 2 18 11.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 3 899 0.3 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <ctype.h>
      31                 :            : #include <stdlib.h>
      32                 :            : #include <stdio.h>
      33                 :            : #include <limits.h>
      34                 :            : #include <rtl/ustrbuf.hxx>
      35                 :            : #include <vcl/svapp.hxx>
      36                 :            : #include <svtools/htmltokn.h>
      37                 :            : #include <comphelper/string.hxx>
      38                 :            : #include "css1kywd.hxx"
      39                 :            : #include "parcss1.hxx"
      40                 :            : 
      41                 :            : 
      42                 :            : // Loop-Check: Um Endlos-Schleifen zu vermeiden, wird in jeder
      43                 :            : // Schalife geprueft, ob ein Fortschritt in der Eingabe-Position
      44                 :            : // stattgefunden hat
      45                 :            : #define LOOP_CHECK
      46                 :            : 
      47                 :            : #ifdef LOOP_CHECK
      48                 :            : 
      49                 :            : #define LOOP_CHECK_DECL \
      50                 :            :     xub_StrLen nOldInPos = STRING_MAXLEN;
      51                 :            : #define LOOP_CHECK_RESTART \
      52                 :            :     nOldInPos = STRING_MAXLEN;
      53                 :            : #define LOOP_CHECK_CHECK( where ) \
      54                 :            :     OSL_ENSURE( nOldInPos!=nInPos || cNextCh==(sal_Unicode)EOF, where );    \
      55                 :            :     if( nOldInPos==nInPos && cNextCh!=(sal_Unicode)EOF )                    \
      56                 :            :         break;                                                              \
      57                 :            :     else                                                                    \
      58                 :            :         nOldInPos = nInPos;
      59                 :            : 
      60                 :            : #else
      61                 :            : 
      62                 :            : #define LOOP_CHECK_DECL
      63                 :            : #define LOOP_CHECK_RESTART
      64                 :            : #define LOOP_CHECK_CHECK( where )
      65                 :            : 
      66                 :            : #endif
      67                 :            : 
      68                 :            : 
      69                 :            : const sal_Int32 MAX_LEN = 1024;
      70                 :            : 
      71                 :            : 
      72                 :          0 : void CSS1Parser::InitRead( const String& rIn )
      73                 :            : {
      74                 :          0 :     nlLineNr = 0;
      75                 :          0 :     nlLinePos = 0;
      76                 :            : 
      77                 :          0 :     bWhiteSpace = sal_True; // Wenn noch nichts gelesen wurde ist das wie WS
      78                 :          0 :     bEOF = sal_False;
      79                 :          0 :     eState = CSS1_PAR_WORKING;
      80                 :          0 :     nValue = 0.;
      81                 :            : 
      82                 :          0 :     aIn = rIn;
      83                 :          0 :     nInPos = 0;
      84                 :          0 :     cNextCh = GetNextChar();
      85                 :          0 :     nToken = GetNextToken();
      86                 :          0 : }
      87                 :            : 
      88                 :          0 : sal_Unicode CSS1Parser::GetNextChar()
      89                 :            : {
      90         [ #  # ]:          0 :     if( nInPos >= aIn.Len() )
      91                 :            :     {
      92                 :          0 :         bEOF = sal_True;
      93                 :          0 :         return (sal_Unicode)EOF;
      94                 :            :     }
      95                 :            : 
      96                 :          0 :     sal_Unicode c = aIn.GetChar( nInPos );
      97                 :          0 :     nInPos++;
      98                 :            : 
      99         [ #  # ]:          0 :     if( c == '\n' )
     100                 :            :     {
     101                 :          0 :         IncLineNr();
     102                 :          0 :         SetLinePos( 1L );
     103                 :            :     }
     104                 :            :     else
     105                 :          0 :         IncLinePos();
     106                 :            : 
     107                 :          0 :     return c;
     108                 :            : }
     109                 :            : 
     110                 :            : // Diese Funktion realisiert den in
     111                 :            : //
     112                 :            : //      http://www.w3.orh/pub/WWW/TR/WD-css1.html
     113                 :            : // bzw. http://www.w3.orh/pub/WWW/TR/WD-css1-960220.html
     114                 :            : //
     115                 :            : // beschriebenen Scanner fuer CSS1. Es handelt sich um eine direkte
     116                 :            : // Umsetzung der dort beschriebenen Lex-Grammatik
     117                 :            : //
     118                 :          0 : CSS1Token CSS1Parser::GetNextToken()
     119                 :            : {
     120                 :          0 :     CSS1Token nRet = CSS1_NULL;
     121                 :          0 :     aToken.Erase();
     122                 :            : 
     123   [ #  #  #  # ]:          0 :     do {
                 [ #  # ]
     124                 :            :         // Merken, ob davor White-Space gelesen wurde
     125                 :          0 :         sal_Bool bPrevWhiteSpace = bWhiteSpace;
     126                 :          0 :         bWhiteSpace = sal_False;
     127                 :            : 
     128                 :          0 :         sal_Bool bNextCh = sal_True;
     129   [ #  #  #  #  :          0 :         switch( cNextCh )
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     130                 :            :         {
     131                 :            :         case '/': // COMMENT | '/'
     132                 :            :             {
     133                 :          0 :                 cNextCh = GetNextChar();
     134         [ #  # ]:          0 :                 if( '*' == cNextCh )
     135                 :            :                 {
     136                 :            :                     // COMMENT
     137                 :          0 :                     cNextCh = GetNextChar();
     138                 :            : 
     139                 :          0 :                     sal_Bool bAsterix = sal_False;
     140 [ #  # ][ #  # ]:          0 :                     while( !(bAsterix && '/'==cNextCh) && !IsEOF() )
         [ #  # ][ #  # ]
     141                 :            :                     {
     142                 :          0 :                         bAsterix = ('*'==cNextCh);
     143                 :          0 :                         cNextCh = GetNextChar();
     144                 :            :                     }
     145                 :            :                 }
     146                 :            :                 else
     147                 :            :                 {
     148                 :            :                     // '/'
     149                 :          0 :                     bNextCh = sal_False;
     150                 :          0 :                     nRet = CSS1_SLASH;
     151                 :            :                 }
     152                 :            :             }
     153                 :          0 :             break;
     154                 :            : 
     155                 :            :         case '@': // '@import' | '@XXX'
     156                 :            :             {
     157                 :          0 :                 cNextCh = GetNextChar();
     158         [ #  # ]:          0 :                 if (comphelper::string::isalphaAscii(cNextCh))
     159                 :            :                 {
     160                 :            :                     // den naechsten Identifer scannen
     161                 :          0 :                     ::rtl::OUStringBuffer sTmpBuffer( 32L );
     162         [ #  # ]:          0 :                     do {
           [ #  #  #  # ]
                 [ #  # ]
     163         [ #  # ]:          0 :                         sTmpBuffer.append( cNextCh );
     164                 :          0 :                         cNextCh = GetNextChar();
     165         [ #  # ]:          0 :                     } while( (comphelper::string::isalnumAscii(cNextCh) ||
     166                 :          0 :                              '-' == cNextCh) && !IsEOF() );
     167                 :            : 
     168 [ #  # ][ #  # ]:          0 :                     aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     169                 :            : 
     170                 :            :                     // und schauen, ob wir ihn kennen
     171      [ #  #  # ]:          0 :                     switch( aToken.GetChar(0) )
     172                 :            :                     {
     173                 :            :                     case 'i':
     174                 :            :                     case 'I':
     175 [ #  # ][ #  # ]:          0 :                         if( aToken.EqualsIgnoreCaseAscii(sCSS1_import) )
     176                 :          0 :                             nRet = CSS1_IMPORT_SYM;
     177                 :          0 :                         break;
     178                 :            : // /Feature: PrintExt
     179                 :            :                     case 'p':
     180                 :            :                     case 'P':
     181 [ #  # ][ #  # ]:          0 :                         if( aToken.EqualsIgnoreCaseAscii(sCSS1_page) )
     182                 :          0 :                             nRet = CSS1_PAGE_SYM;
     183                 :          0 :                         break;
     184                 :            : // /Feature: PrintExt
     185                 :            :                     }
     186                 :            : 
     187                 :            :                     // Fehlerbehandlung: '@ident' und alles bis
     188                 :            :                     // zu einem Semikolon der dem Ende des folgenden
     189                 :            :                     // Blocks ignorieren
     190         [ #  # ]:          0 :                     if( CSS1_NULL==nRet )
     191                 :            :                     {
     192         [ #  # ]:          0 :                         aToken.Erase();
     193                 :          0 :                         sal_uInt16 nBlockLvl = 0;
     194                 :          0 :                         sal_Unicode cQuoteCh = 0;
     195                 :          0 :                         sal_Bool bDone = sal_False, bEscape = sal_False;
     196 [ #  # ][ #  # ]:          0 :                         while( !bDone && !IsEOF() )
                 [ #  # ]
     197                 :            :                         {
     198                 :          0 :                             sal_Bool bOldEscape = bEscape;
     199                 :          0 :                             bEscape = sal_False;
     200   [ #  #  #  #  :          0 :                             switch( cNextCh )
                   #  # ]
     201                 :            :                             {
     202                 :            :                             case '{':
     203 [ #  # ][ #  # ]:          0 :                                 if( !cQuoteCh && !bOldEscape )
     204                 :          0 :                                     nBlockLvl++;
     205                 :          0 :                                 break;
     206                 :            :                             case ';':
     207 [ #  # ][ #  # ]:          0 :                                 if( !cQuoteCh && !bOldEscape )
     208                 :          0 :                                     bDone = nBlockLvl==0;
     209                 :          0 :                                 break;
     210                 :            :                             case '}':
     211 [ #  # ][ #  # ]:          0 :                                 if( !cQuoteCh && !bOldEscape )
     212                 :          0 :                                     bDone = --nBlockLvl==0;
     213                 :          0 :                                 break;
     214                 :            :                             case '\"':
     215                 :            :                             case '\'':
     216         [ #  # ]:          0 :                                 if( !bOldEscape )
     217                 :            :                                 {
     218         [ #  # ]:          0 :                                     if( cQuoteCh )
     219                 :            :                                     {
     220         [ #  # ]:          0 :                                         if( cQuoteCh == cNextCh )
     221                 :          0 :                                             cQuoteCh = 0;
     222                 :            :                                     }
     223                 :            :                                     else
     224                 :            :                                     {
     225                 :          0 :                                         cQuoteCh = cNextCh;
     226                 :            :                                     }
     227                 :            :                                 }
     228                 :          0 :                                 break;
     229                 :            :                             case '\\':
     230         [ #  # ]:          0 :                                 if( !bOldEscape )
     231                 :          0 :                                     bEscape = sal_True;
     232                 :          0 :                                 break;
     233                 :            :                             }
     234                 :          0 :                             cNextCh = GetNextChar();
     235                 :            :                         }
     236                 :            :                     }
     237                 :            : 
     238                 :          0 :                     bNextCh = sal_False;
     239                 :            :                 }
     240                 :            :             }
     241                 :          0 :             break;
     242                 :            : 
     243                 :            :         case '!': // '!' 'legal' | '!' 'important' | syntax error
     244                 :            :             {
     245                 :            :                 // White Space ueberlesen
     246                 :          0 :                 cNextCh = GetNextChar();
     247 [ #  # ][ #  # ]:          0 :                 while( ( ' ' == cNextCh ||
           [ #  #  #  # ]
                 [ #  # ]
     248                 :          0 :                        (cNextCh >= 0x09 && cNextCh <= 0x0d) ) && !IsEOF() )
     249                 :            :                 {
     250                 :          0 :                     bWhiteSpace = sal_True;
     251                 :          0 :                     cNextCh = GetNextChar();
     252                 :            :                 }
     253                 :            : 
     254 [ #  # ][ #  # ]:          0 :                 if( 'i'==cNextCh || 'I'==cNextCh)
     255                 :            :                 {
     256                 :            :                     // den naechsten Identifer scannen
     257                 :          0 :                     ::rtl::OUStringBuffer sTmpBuffer( 32L );
     258         [ #  # ]:          0 :                     do {
           [ #  #  #  # ]
                 [ #  # ]
     259         [ #  # ]:          0 :                         sTmpBuffer.append( cNextCh );
     260                 :          0 :                         cNextCh = GetNextChar();
     261         [ #  # ]:          0 :                     } while( (comphelper::string::isalnumAscii(cNextCh) ||
     262                 :          0 :                              '-' == cNextCh) && !IsEOF() );
     263                 :            : 
     264 [ #  # ][ #  # ]:          0 :                     aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     265                 :            : 
     266 [ #  # ][ #  # ]:          0 :                     if( ('i'==aToken.GetChar(0) || 'I'==aToken.GetChar(0)) &&
         [ #  # ][ #  # ]
     267         [ #  # ]:          0 :                         aToken.EqualsIgnoreCaseAscii(sCSS1_important) )
     268                 :            :                     {
     269                 :            :                         // '!' 'important'
     270                 :          0 :                         nRet = CSS1_IMPORTANT_SYM;
     271                 :            :                     }
     272                 :            :                     else
     273                 :            :                     {
     274                 :            :                         // Fehlerbehandlung: '!' ignorieren, IDENT nicht
     275                 :          0 :                         nRet = CSS1_IDENT;
     276                 :            :                     }
     277                 :            : 
     278                 :          0 :                     bWhiteSpace = sal_False;
     279                 :          0 :                     bNextCh = sal_False;
     280                 :            :                 }
     281                 :            :                 else
     282                 :            :                 {
     283                 :            :                     // Fehlerbehandlung: '!' ignorieren
     284                 :          0 :                     bNextCh = sal_False;
     285                 :            :                 }
     286                 :            :             }
     287                 :          0 :             break;
     288                 :            : 
     289                 :            :         case '\"':
     290                 :            :         case '\'': // STRING
     291                 :            :             {
     292                 :            :                 // \... geht noch nicht!!!
     293                 :          0 :                 sal_Unicode cQuoteChar = cNextCh;
     294                 :          0 :                 cNextCh = GetNextChar();
     295                 :            : 
     296                 :          0 :                 ::rtl::OUStringBuffer sTmpBuffer( MAX_LEN );
     297         [ #  # ]:          0 :                 do {
           [ #  #  #  # ]
     298         [ #  # ]:          0 :                     sTmpBuffer.append( cNextCh );
     299                 :          0 :                     cNextCh = GetNextChar();
     300                 :          0 :                 } while( cQuoteChar != cNextCh && !IsEOF() );
     301                 :            : 
     302 [ #  # ][ #  # ]:          0 :                 aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     303                 :            : 
     304                 :          0 :                 nRet = CSS1_STRING;
     305                 :            :             }
     306                 :          0 :             break;
     307                 :            : 
     308                 :            :         case '0':
     309                 :            :         case '1':
     310                 :            :         case '2':
     311                 :            :         case '3':
     312                 :            :         case '4':
     313                 :            :         case '5':
     314                 :            :         case '6':
     315                 :            :         case '7':
     316                 :            :         case '8':
     317                 :            :         case '9': // NUMBER | PERCENTAGE | LENGTH
     318                 :            :             {
     319                 :            :                 // die aktuelle Position retten
     320                 :          0 :                 xub_StrLen nInPosSave = nInPos;
     321                 :          0 :                 sal_Unicode cNextChSave = cNextCh;
     322                 :          0 :                 sal_uInt32 nlLineNrSave = nlLineNr;
     323                 :          0 :                 sal_uInt32 nlLinePosSave = nlLinePos;
     324                 :          0 :                 sal_Bool bEOFSave = bEOF;
     325                 :            : 
     326                 :            :                 // erstmal versuchen eine Hex-Zahl zu scannen
     327                 :          0 :                 ::rtl::OUStringBuffer sTmpBuffer( 16 );
     328 [ #  # ][ #  # ]:          0 :                 do {
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
     329         [ #  # ]:          0 :                     sTmpBuffer.append( cNextCh );
     330                 :          0 :                     cNextCh = GetNextChar();
     331                 :          0 :                 } while( sTmpBuffer.getLength() < 7 &&
     332                 :            :                          ( ('0'<=cNextCh && '9'>=cNextCh) ||
     333                 :            :                            ('A'<=cNextCh && 'F'>=cNextCh) ||
     334                 :            :                            ('a'<=cNextCh && 'f'>=cNextCh) ) &&
     335                 :          0 :                          !IsEOF() );
     336                 :            : 
     337         [ #  # ]:          0 :                 if( sTmpBuffer.getLength()==6 )
     338                 :            :                 {
     339                 :            :                     // wir haben eine hexadezimale Farbe gefunden
     340 [ #  # ][ #  # ]:          0 :                     aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     341                 :          0 :                     nRet = CSS1_HEXCOLOR;
     342                 :          0 :                     bNextCh = sal_False;
     343                 :            : 
     344                 :            :                     break;
     345                 :            :                 }
     346                 :            : 
     347                 :            :                 // sonst versuchen wir es mit einer Zahl
     348                 :          0 :                 nInPos = nInPosSave;
     349                 :          0 :                 cNextCh = cNextChSave;
     350                 :          0 :                 nlLineNr = nlLineNrSave;
     351                 :          0 :                 nlLinePos = nlLinePosSave;
     352                 :          0 :                 bEOF = bEOFSave;
     353                 :            : 
     354                 :            :                 // erstmal die Zahl scannen
     355         [ #  # ]:          0 :                 sTmpBuffer.setLength( 0L );
     356         [ #  # ]:          0 :                 do {
           [ #  #  #  # ]
         [ #  # ][ #  # ]
     357         [ #  # ]:          0 :                     sTmpBuffer.append( cNextCh );
     358                 :          0 :                     cNextCh = GetNextChar();
     359                 :            :                 } while( (('0'<=cNextCh && '9'>=cNextCh) || '.'==cNextCh) &&
     360                 :          0 :                          !IsEOF() );
     361                 :            : 
     362 [ #  # ][ #  # ]:          0 :                 aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     363         [ #  # ]:          0 :                 nValue = rtl::OUString(aToken).toDouble();
     364                 :            : 
     365                 :            :                 // White Space ueberlesen
     366 [ #  # ][ #  # ]:          0 :                 while( ( ' ' == cNextCh ||
           [ #  #  #  # ]
                 [ #  # ]
     367                 :          0 :                        (cNextCh >= 0x09 && cNextCh <= 0x0d) ) && !IsEOF() )
     368                 :            :                 {
     369                 :          0 :                     bWhiteSpace = sal_True;
     370                 :          0 :                     cNextCh = GetNextChar();
     371                 :            :                 }
     372                 :            : 
     373                 :            :                 // und nun Schauen, ob es eine Einheit gibt
     374      [ #  #  # ]:          0 :                 switch( cNextCh )
     375                 :            :                 {
     376                 :            :                 case '%': // PERCENTAGE
     377                 :          0 :                     bWhiteSpace = sal_False;
     378                 :          0 :                     nRet = CSS1_PERCENTAGE;
     379                 :          0 :                     break;
     380                 :            : 
     381                 :            :                 case 'c':
     382                 :            :                 case 'C': // LENGTH cm | LENGTH IDENT
     383                 :            :                 case 'e':
     384                 :            :                 case 'E': // LENGTH (em | ex) | LENGTH IDENT
     385                 :            :                 case 'i':
     386                 :            :                 case 'I': // LENGTH inch | LENGTH IDENT
     387                 :            :                 case 'p':
     388                 :            :                 case 'P': // LENGTH (pt | px | pc) | LENGTH IDENT
     389                 :            :                 case 'm':
     390                 :            :                 case 'M': // LENGTH mm | LENGTH IDENT
     391                 :            :                     {
     392                 :            :                         // die aktuelle Position retten
     393                 :          0 :                         xub_StrLen nInPosOld = nInPos;
     394                 :          0 :                         sal_Unicode cNextChOld = cNextCh;
     395                 :          0 :                         sal_uLong nlLineNrOld  = nlLineNr;
     396                 :          0 :                         sal_uLong nlLinePosOld = nlLinePos;
     397                 :          0 :                         sal_Bool bEOFOld = bEOF;
     398                 :            : 
     399                 :            :                         // den naechsten Identifer scannen
     400         [ #  # ]:          0 :                         String aIdent;
     401                 :          0 :                         ::rtl::OUStringBuffer sTmpBuffer2( 64L );
     402         [ #  # ]:          0 :                         do {
           [ #  #  #  # ]
                 [ #  # ]
     403         [ #  # ]:          0 :                             sTmpBuffer2.append( cNextCh );
     404                 :          0 :                             cNextCh = GetNextChar();
     405         [ #  # ]:          0 :                         } while( (comphelper::string::isalnumAscii(cNextCh) ||
     406                 :          0 :                                  '-' == cNextCh) && !IsEOF() );
     407                 :            : 
     408 [ #  # ][ #  # ]:          0 :                         aIdent += String(sTmpBuffer2.makeStringAndClear());
         [ #  # ][ #  # ]
     409                 :            : 
     410                 :            :                         // Ist es eine Einheit?
     411                 :          0 :                         const sal_Char *pCmp1 = 0, *pCmp2 = 0, *pCmp3 = 0;
     412                 :          0 :                         double nScale1 = 1., nScale2 = 1.;
     413                 :          0 :                         CSS1Token nToken1 = CSS1_LENGTH,
     414                 :          0 :                                   nToken2 = CSS1_LENGTH,
     415                 :          0 :                                   nToken3 = CSS1_LENGTH;
     416   [ #  #  #  #  :          0 :                         switch( aIdent.GetChar(0) )
                   #  # ]
     417                 :            :                         {
     418                 :            :                         case 'c':
     419                 :            :                         case 'C':
     420                 :          0 :                             pCmp1 = sCSS1_UNIT_cm;
     421                 :          0 :                             nScale1 = (72.*20.)/2.54; // twip
     422                 :          0 :                             break;
     423                 :            :                         case 'e':
     424                 :            :                         case 'E':
     425                 :          0 :                             pCmp1 = sCSS1_UNIT_em;
     426                 :          0 :                             nToken1 = CSS1_EMS;
     427                 :            : 
     428                 :          0 :                             pCmp2 = sCSS1_UNIT_ex;
     429                 :          0 :                             nToken2 = CSS1_EMX;
     430                 :          0 :                             break;
     431                 :            :                         case 'i':
     432                 :            :                         case 'I':
     433                 :          0 :                             pCmp1 = sCSS1_UNIT_inch;
     434                 :          0 :                             nScale1 = 72.*20.; // twip
     435                 :          0 :                             break;
     436                 :            :                         case 'm':
     437                 :            :                         case 'M':
     438                 :          0 :                             pCmp1 = sCSS1_UNIT_mm;
     439                 :          0 :                             nScale1 = (72.*20.)/25.4; // twip
     440                 :          0 :                             break;
     441                 :            :                         case 'p':
     442                 :            :                         case 'P':
     443                 :          0 :                             pCmp1 = sCSS1_UNIT_pt;
     444                 :          0 :                             nScale1 = 20.; // twip
     445                 :            : 
     446                 :          0 :                             pCmp2 = sCSS1_UNIT_pc;
     447                 :          0 :                             nScale2 = 12.*20.; // twip
     448                 :            : 
     449                 :          0 :                             pCmp3 = sCSS1_UNIT_px;
     450                 :          0 :                             nToken3 = CSS1_PIXLENGTH;
     451                 :          0 :                             break;
     452                 :            :                         }
     453                 :            : 
     454                 :          0 :                         double nScale = 0.0;
     455                 :            :                         OSL_ENSURE( pCmp1, "Wo kommt das erste Zeichen her?" );
     456 [ #  # ][ #  # ]:          0 :                         if( aIdent.EqualsIgnoreCaseAscii(pCmp1) )
     457                 :            :                         {
     458                 :          0 :                             nScale = nScale1;
     459                 :          0 :                             nRet = nToken1;
     460                 :            :                         }
     461 [ #  # ][ #  # ]:          0 :                         else if( pCmp2 &&
                 [ #  # ]
     462         [ #  # ]:          0 :                                  aIdent.EqualsIgnoreCaseAscii(pCmp2) )
     463                 :            :                         {
     464                 :          0 :                             nScale = nScale2;
     465                 :          0 :                             nRet = nToken2;
     466                 :            :                         }
     467 [ #  # ][ #  # ]:          0 :                         else if( pCmp3 &&
                 [ #  # ]
     468         [ #  # ]:          0 :                                  aIdent.EqualsIgnoreCaseAscii(pCmp3) )
     469                 :            :                         {
     470                 :          0 :                             nScale =  1.; // nScale3
     471                 :          0 :                             nRet = nToken3;
     472                 :            :                         }
     473                 :            :                         else
     474                 :            :                         {
     475                 :          0 :                             nRet = CSS1_NUMBER;
     476                 :            :                         }
     477                 :            : 
     478 [ #  # ][ #  # ]:          0 :                         if( CSS1_LENGTH==nRet && nScale!=1.0 )
     479                 :          0 :                             nValue *= nScale;
     480                 :            : 
     481         [ #  # ]:          0 :                         if( nRet == CSS1_NUMBER )
     482                 :            :                         {
     483                 :          0 :                             nInPos = nInPosOld;
     484                 :          0 :                             cNextCh = cNextChOld;
     485                 :          0 :                             nlLineNr = nlLineNrOld;
     486                 :          0 :                             nlLinePos = nlLinePosOld;
     487                 :          0 :                             bEOF = bEOFOld;
     488                 :            :                         }
     489                 :            :                         else
     490                 :            :                         {
     491                 :          0 :                             bWhiteSpace = sal_False;
     492                 :            :                         }
     493         [ #  # ]:          0 :                         bNextCh = sal_False;
     494                 :            :                     }
     495                 :          0 :                     break;
     496                 :            :                 default: // NUMBER IDENT
     497                 :          0 :                     bNextCh = sal_False;
     498                 :          0 :                     nRet = CSS1_NUMBER;
     499                 :          0 :                     break;
     500         [ #  # ]:          0 :                 }
     501                 :            :             }
     502                 :          0 :             break;
     503                 :            : 
     504                 :            :         case ':': // ':'
     505                 :            :             // link/visited/active abfangen !!!
     506                 :          0 :             nRet = CSS1_COLON;
     507                 :          0 :             break;
     508                 :            : 
     509                 :            :         case '.': // DOT_W_WS | DOT_WO_WS
     510         [ #  # ]:          0 :             nRet = bPrevWhiteSpace ? CSS1_DOT_W_WS : CSS1_DOT_WO_WS;
     511                 :          0 :             break;
     512                 :            : 
     513                 :            :         case '+': // '+'
     514                 :          0 :             nRet = CSS1_PLUS;
     515                 :          0 :             break;
     516                 :            : 
     517                 :            :         case '-': // '-'
     518                 :          0 :             nRet = CSS1_MINUS;
     519                 :          0 :             break;
     520                 :            : 
     521                 :            :         case '{': // '{'
     522                 :          0 :             nRet = CSS1_OBRACE;
     523                 :          0 :             break;
     524                 :            : 
     525                 :            :         case '}': // '}'
     526                 :          0 :             nRet = CSS1_CBRACE;
     527                 :          0 :             break;
     528                 :            : 
     529                 :            :         case ';': // ';'
     530                 :          0 :             nRet = CSS1_SEMICOLON;
     531                 :          0 :             break;
     532                 :            : 
     533                 :            :         case ',': // ','
     534                 :          0 :             nRet = CSS1_COMMA;
     535                 :          0 :             break;
     536                 :            : 
     537                 :            :         case '#': // '#'
     538                 :          0 :             cNextCh = GetNextChar();
     539 [ #  # ][ #  # ]:          0 :             if( ('0'<=cNextCh && '9'>=cNextCh) ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     540                 :            :                 ('a'<=cNextCh && 'f'>=cNextCh) ||
     541                 :            :                 ('A'<=cNextCh && 'F'>=cNextCh) )
     542                 :            :             {
     543                 :            :                 // die aktuelle Position retten
     544                 :          0 :                 xub_StrLen nInPosSave = nInPos;
     545                 :          0 :                 sal_Unicode cNextChSave = cNextCh;
     546                 :          0 :                 sal_uLong nlLineNrSave = nlLineNr;
     547                 :          0 :                 sal_uLong nlLinePosSave = nlLinePos;
     548                 :          0 :                 sal_Bool bEOFSave = bEOF;
     549                 :            : 
     550                 :            :                 // erstmal versuchen eine Hex-Zahl zu scannen
     551                 :          0 :                 ::rtl::OUStringBuffer sTmpBuffer( 6L );
     552 [ #  # ][ #  # ]:          0 :                 do {
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
     553         [ #  # ]:          0 :                     sTmpBuffer.append( cNextCh );
     554                 :          0 :                     cNextCh = GetNextChar();
     555                 :          0 :                 } while( sTmpBuffer.getLength() < 7 &&
     556                 :            :                          ( ('0'<=cNextCh && '9'>=cNextCh) ||
     557                 :            :                            ('A'<=cNextCh && 'F'>=cNextCh) ||
     558                 :            :                            ('a'<=cNextCh && 'f'>=cNextCh) ) &&
     559                 :          0 :                          !IsEOF() );
     560                 :            : 
     561 [ #  # ][ #  # ]:          0 :                 if( sTmpBuffer.getLength()==6 || sTmpBuffer.getLength()==3 )
                 [ #  # ]
     562                 :            :                 {
     563                 :            :                     // wir haben eine hexadezimale Farbe gefunden
     564 [ #  # ][ #  # ]:          0 :                     aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     565                 :          0 :                     nRet = CSS1_HEXCOLOR;
     566                 :          0 :                     bNextCh = sal_False;
     567                 :            : 
     568                 :            :                     break;
     569                 :            :                 }
     570                 :            : 
     571                 :            :                 // sonst versuchen wir es mit einer Zahl
     572                 :          0 :                 nInPos = nInPosSave;
     573                 :          0 :                 cNextCh = cNextChSave;
     574                 :          0 :                 nlLineNr = nlLineNrSave;
     575                 :          0 :                 nlLinePos = nlLinePosSave;
     576         [ #  # ]:          0 :                 bEOF = bEOFSave;
     577                 :            :             }
     578                 :            : 
     579                 :          0 :             nRet = CSS1_HASH;
     580                 :          0 :             bNextCh = sal_False;
     581                 :          0 :             break;
     582                 :            : 
     583                 :            :         case ' ':
     584                 :            :         case '\t':
     585                 :            :         case '\r':
     586                 :            :         case '\n': // White-Space
     587                 :          0 :             bWhiteSpace = sal_True;
     588                 :          0 :             break;
     589                 :            : 
     590                 :            :         case (sal_Unicode)EOF:
     591         [ #  # ]:          0 :             if( IsEOF() )
     592                 :            :             {
     593                 :          0 :                 eState = CSS1_PAR_ACCEPTED;
     594                 :          0 :                 bNextCh = sal_False;
     595                 :          0 :                 break;
     596                 :            :             }
     597                 :            :             // kein break;
     598                 :            : 
     599                 :            :         default: // IDENT | syntax error
     600         [ #  # ]:          0 :             if (comphelper::string::isalphaAscii(cNextCh))
     601                 :            :             {
     602                 :            :                 // IDENT
     603                 :            : 
     604                 :          0 :                 sal_Bool bHexColor = sal_True;
     605                 :            : 
     606                 :            :                 // den naechsten Identifer scannen
     607                 :          0 :                 ::rtl::OUStringBuffer sTmpBuffer( 64L );
     608         [ #  # ]:          0 :                 do {
           [ #  #  #  # ]
                 [ #  # ]
     609         [ #  # ]:          0 :                     sTmpBuffer.append( cNextCh );
     610         [ #  # ]:          0 :                     if( bHexColor )
     611                 :            :                     {
     612                 :          0 :                         bHexColor =  sTmpBuffer.getLength()<7 &&
     613                 :            :                                      ( ('0'<=cNextCh && '9'>=cNextCh) ||
     614                 :            :                                        ('A'<=cNextCh && 'F'>=cNextCh) ||
     615 [ #  # ][ #  # ]:          0 :                                        ('a'<=cNextCh && 'f'>=cNextCh) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     616                 :            :                     }
     617                 :          0 :                     cNextCh = GetNextChar();
     618         [ #  # ]:          0 :                 } while( (comphelper::string::isalnumAscii(cNextCh) ||
     619                 :          0 :                            '-' == cNextCh) && !IsEOF() );
     620                 :            : 
     621 [ #  # ][ #  # ]:          0 :                 aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     622                 :            : 
     623 [ #  # ][ #  # ]:          0 :                 if( bHexColor && sTmpBuffer.getLength()==6 )
                 [ #  # ]
     624                 :            :                 {
     625                 :          0 :                     bNextCh = sal_False;
     626                 :          0 :                     nRet = CSS1_HEXCOLOR;
     627                 :            : 
     628                 :            :                     break;
     629                 :            :                 }
     630   [ #  #  #  #  :          0 :                 if( '('==cNextCh &&
           #  # ][ #  #  
             #  #  #  # ]
         [ #  # ][ #  # ]
     631                 :          0 :                     ( (('u'==aToken.GetChar(0) || 'U'==aToken.GetChar(0)) &&
     632         [ #  # ]:          0 :                        aToken.EqualsIgnoreCaseAscii(sCSS1_url)) ||
     633                 :          0 :                       (('r'==aToken.GetChar(0) || 'R'==aToken.GetChar(0)) &&
     634         [ #  # ]:          0 :                        aToken.EqualsIgnoreCaseAscii(sCSS1_rgb)) ) )
     635                 :            :                 {
     636                 :          0 :                     sal_uInt16 nNestCnt = 0;
     637                 :          0 :                     ::rtl::OUStringBuffer sTmpBuffer2( 64L );
     638   [ #  #  #  # ]:          0 :                     do {
         [ #  # ][ #  # ]
     639         [ #  # ]:          0 :                         sTmpBuffer2.append( cNextCh );
     640      [ #  #  # ]:          0 :                         switch( cNextCh )
     641                 :            :                         {
     642                 :          0 :                         case '(':   nNestCnt++; break;
     643                 :          0 :                         case ')':   nNestCnt--; break;
     644                 :            :                         }
     645                 :          0 :                         cNextCh = GetNextChar();
     646                 :          0 :                     } while( (nNestCnt>1 || ')'!=cNextCh) && !IsEOF() );
     647         [ #  # ]:          0 :                     sTmpBuffer2.append( cNextCh );
     648 [ #  # ][ #  # ]:          0 :                     aToken += String(sTmpBuffer2.makeStringAndClear());
         [ #  # ][ #  # ]
     649                 :          0 :                     bNextCh = sal_True;
     650                 :          0 :                     nRet = 'u'==aToken.GetChar(0) || 'U'==aToken.GetChar(0)
     651                 :            :                                 ? CSS1_URL
     652   [ #  #  #  # ]:          0 :                                 : CSS1_RGB;
     653                 :            :                 }
     654                 :            :                 else
     655                 :            :                 {
     656                 :          0 :                     bNextCh = sal_False;
     657                 :          0 :                     nRet = CSS1_IDENT;
     658         [ #  # ]:          0 :                 }
     659                 :            :             }
     660                 :            :             // Fehlerbehandlung: Zeichen ignorieren
     661                 :          0 :             break;
     662                 :            :         }
     663         [ #  # ]:          0 :         if( bNextCh )
     664                 :          0 :             cNextCh = GetNextChar();
     665                 :            : 
     666                 :          0 :     } while( CSS1_NULL==nRet && IsParserWorking() );
     667                 :            : 
     668                 :          0 :     return nRet;
     669                 :            : }
     670                 :            : 
     671                 :            : 
     672                 :            : // Dies folegenden Funktionen realisieren den in
     673                 :            : //
     674                 :            : //      http://www.w3.orh/pub/WWW/TR/WD-css1.html
     675                 :            : // bzw. http://www.w3.orh/pub/WWW/TR/WD-css1-960220.html
     676                 :            : //
     677                 :            : // beschriebenen Parser fuer CSS1. Es handelt sich um eine direkte
     678                 :            : // Umsetzung der dort beschriebenen Grammatik
     679                 :            : 
     680                 :            : // stylesheet
     681                 :            : //  : import* rule*
     682                 :            : //
     683                 :            : // import
     684                 :            : //  : IMPORT_SYM url
     685                 :            : //
     686                 :            : // url
     687                 :            : //  : STRING
     688                 :            : //
     689                 :          0 : void CSS1Parser::ParseStyleSheet()
     690                 :            : {
     691                 :          0 :     LOOP_CHECK_DECL
     692                 :            : 
     693                 :            :     // import*
     694                 :          0 :     sal_Bool bDone = sal_False;
     695 [ #  # ][ #  # ]:          0 :     while( !bDone && IsParserWorking() )
                 [ #  # ]
     696                 :            :     {
     697 [ #  # ][ #  # ]:          0 :         LOOP_CHECK_CHECK( "Endlos-Schleife in ParseStyleSheet()/import *" )
     698                 :            : 
     699      [ #  #  # ]:          0 :         switch( nToken )
     700                 :            :         {
     701                 :            :         case CSS1_IMPORT_SYM:
     702                 :            :             // IMPORT_SYM url
     703                 :            :             // url ueberspringen wir ungeprueft
     704                 :          0 :             nToken = GetNextToken();
     705                 :          0 :             break;
     706                 :            :         case CSS1_IDENT:            // Look-Aheads
     707                 :            :         case CSS1_DOT_W_WS:
     708                 :            :         case CSS1_HASH:
     709                 :            : // /Feature: PrintExt
     710                 :            :         case CSS1_PAGE_SYM:
     711                 :            : // /Feature: PrintExt
     712                 :            :             // rule
     713                 :          0 :             bDone = sal_True;
     714                 :          0 :             break;
     715                 :            :         default:
     716                 :            :             // Fehlerbehandlung: ueberlesen
     717                 :          0 :             break;
     718                 :            :         }
     719                 :            : 
     720         [ #  # ]:          0 :         if( !bDone )
     721                 :          0 :             nToken = GetNextToken();
     722                 :            :     }
     723                 :            : 
     724                 :          0 :     LOOP_CHECK_RESTART
     725                 :            : 
     726                 :            :     // rule *
     727         [ #  # ]:          0 :     while( IsParserWorking() )
     728                 :            :     {
     729 [ #  # ][ #  # ]:          0 :         LOOP_CHECK_CHECK( "Endlos-Schleife in ParseStyleSheet()/rule *" )
     730                 :            : 
     731         [ #  # ]:          0 :         switch( nToken )
     732                 :            :         {
     733                 :            :         case CSS1_IDENT:        // Look-Aheads
     734                 :            :         case CSS1_DOT_W_WS:
     735                 :            :         case CSS1_HASH:
     736                 :            : // /Feature: PrintExt
     737                 :            :         case CSS1_PAGE_SYM:
     738                 :            : // /Feature: PrintExt
     739                 :            :             // rule
     740                 :          0 :             ParseRule();
     741                 :          0 :             break;
     742                 :            :         default:
     743                 :            :             // Fehlerbehandlung: ueberlesen
     744                 :          0 :             nToken = GetNextToken();
     745                 :          0 :             break;
     746                 :            :         }
     747                 :            :     }
     748                 :          0 : }
     749                 :            : 
     750                 :            : // rule
     751                 :            : //  : selector [ ',' selector ]*
     752                 :            : //    '{' declaration [ ';' declaration ]* '}'
     753                 :            : //
     754                 :          0 : void CSS1Parser::ParseRule()
     755                 :            : {
     756                 :            :     // selector
     757         [ #  # ]:          0 :     CSS1Selector *pSelector = ParseSelector();
     758         [ #  # ]:          0 :     if( !pSelector )
     759                 :            :         return;
     760                 :            : 
     761                 :            :     // Selektor verarbeiten
     762 [ #  # ][ #  # ]:          0 :     if( SelectorParsed( pSelector, sal_True ) )
     763 [ #  # ][ #  # ]:          0 :         delete pSelector;
     764                 :            : 
     765                 :          0 :     LOOP_CHECK_DECL
     766                 :            : 
     767                 :            :     // [ ',' selector ]*
     768 [ #  # ][ #  # ]:          0 :     while( CSS1_COMMA==nToken && IsParserWorking() )
                 [ #  # ]
     769                 :            :     {
     770 [ #  # ][ #  # ]:          0 :         LOOP_CHECK_CHECK( "Endlos-Schleife in ParseRule()/selector *" )
     771                 :            : 
     772                 :            :         // ',' ueberelesen
     773         [ #  # ]:          0 :         nToken = GetNextToken();
     774                 :            : 
     775                 :            :         // selector
     776         [ #  # ]:          0 :         pSelector = ParseSelector();
     777         [ #  # ]:          0 :         if( !pSelector )
     778                 :            :             return;
     779                 :            : 
     780                 :            :         // Selektor verarbeiten
     781 [ #  # ][ #  # ]:          0 :         if( SelectorParsed( pSelector, sal_False ) )
     782 [ #  # ][ #  # ]:          0 :             delete pSelector;
     783                 :            :     }
     784                 :            : 
     785                 :            :     // '{'
     786         [ #  # ]:          0 :     if( CSS1_OBRACE != nToken )
     787                 :            :         return;
     788         [ #  # ]:          0 :     nToken = GetNextToken();
     789                 :            : 
     790                 :            :     // declaration
     791         [ #  # ]:          0 :     String aProperty;
     792         [ #  # ]:          0 :     CSS1Expression *pExpr = ParseDeclaration( aProperty );
     793         [ #  # ]:          0 :     if( !pExpr )
     794                 :            :         return;
     795                 :            : 
     796                 :            :     // expression verarbeiten
     797 [ #  # ][ #  # ]:          0 :     if( DeclarationParsed( aProperty, pExpr ) )
     798 [ #  # ][ #  # ]:          0 :         delete pExpr;
     799                 :            : 
     800                 :          0 :     LOOP_CHECK_RESTART
     801                 :            : 
     802                 :            :     // [ ';' declaration ]*
     803 [ #  # ][ #  # ]:          0 :     while( CSS1_SEMICOLON==nToken && IsParserWorking() )
                 [ #  # ]
     804                 :            :     {
     805 [ #  # ][ #  # ]:          0 :         LOOP_CHECK_CHECK( "Endlos-Schleife in ParseRule()/declaration *" )
     806                 :            : 
     807                 :            :         // ';'
     808         [ #  # ]:          0 :         nToken = GetNextToken();
     809                 :            : 
     810                 :            :         // declaration
     811         [ #  # ]:          0 :         if( CSS1_IDENT == nToken )
     812                 :            :         {
     813         [ #  # ]:          0 :             CSS1Expression *pExp = ParseDeclaration( aProperty );
     814         [ #  # ]:          0 :             if( pExp )
     815                 :            :             {
     816                 :            :                 // expression verarbeiten
     817 [ #  # ][ #  # ]:          0 :                 if( DeclarationParsed( aProperty, pExp ) )
     818 [ #  # ][ #  # ]:          0 :                     delete pExp;
     819                 :            :             }
     820                 :            :         }
     821                 :            :     }
     822                 :            : 
     823                 :            :     // '}'
     824         [ #  # ]:          0 :     if( CSS1_CBRACE == nToken )
     825 [ #  # ][ #  # ]:          0 :         nToken = GetNextToken();
                 [ #  # ]
     826                 :            : }
     827                 :            : 
     828                 :            : // selector
     829                 :            : //  : simple_selector+ [ ':' pseudo_element ]?
     830                 :            : //
     831                 :            : // simple_selector
     832                 :            : //  : element_name [ DOT_WO_WS class ]?
     833                 :            : //  | DOT_W_WS class
     834                 :            : //  | id_selector
     835                 :            : //
     836                 :            : // element_name
     837                 :            : //  : IDENT
     838                 :            : //
     839                 :            : // class
     840                 :            : //  : IDENT
     841                 :            : //
     842                 :            : // id_selector
     843                 :            : //  : '#' IDENT
     844                 :            : //
     845                 :            : // pseude_element
     846                 :            : //  : IDENT
     847                 :            : //
     848                 :          0 : CSS1Selector *CSS1Parser::ParseSelector()
     849                 :            : {
     850                 :          0 :     CSS1Selector *pRoot = 0, *pLast = 0;
     851                 :            : 
     852                 :          0 :     sal_Bool bDone = sal_False;
     853                 :          0 :     CSS1Selector *pNew = 0;
     854                 :            : 
     855                 :          0 :     LOOP_CHECK_DECL
     856                 :            : 
     857                 :            :     // simple_selector+
     858 [ #  # ][ #  # ]:          0 :     while( !bDone && IsParserWorking() )
                 [ #  # ]
     859                 :            :     {
     860 [ #  # ][ #  # ]:          0 :         LOOP_CHECK_CHECK( "Endlos-Schleife in ParseSelector()" )
     861                 :            : 
     862                 :          0 :         sal_Bool bNextToken = sal_True;
     863                 :            : 
     864   [ #  #  #  #  :          0 :         switch( nToken )
                      # ]
     865                 :            :         {
     866                 :            :         case CSS1_IDENT:
     867                 :            :             {
     868                 :            :                 // element_name [ DOT_WO_WS class ]?
     869                 :            : 
     870                 :            :                 // element_name
     871         [ #  # ]:          0 :                 String aElement = aToken;
     872                 :          0 :                 CSS1SelectorType eType = CSS1_SELTYPE_ELEMENT;
     873         [ #  # ]:          0 :                 nToken = GetNextToken();
     874                 :            : 
     875         [ #  # ]:          0 :                 if( CSS1_DOT_WO_WS == nToken )
     876                 :            :                 {
     877                 :            :                     // DOT_WO_WS
     878         [ #  # ]:          0 :                     nToken = GetNextToken();
     879                 :            : 
     880                 :            :                     // class
     881         [ #  # ]:          0 :                     if( CSS1_IDENT == nToken )
     882                 :            :                     {
     883 [ #  # ][ #  # ]:          0 :                         (aElement += '.') += aToken;
     884                 :          0 :                         eType = CSS1_SELTYPE_ELEM_CLASS;
     885                 :            :                     }
     886                 :            :                     else
     887                 :            :                     {
     888                 :            :                         // class fehlt
     889                 :          0 :                         return pRoot;
     890                 :            :                     }
     891                 :            :                 }
     892                 :            :                 else
     893                 :            :                 {
     894                 :            :                     // das war jetzt ein Look-Ahead
     895                 :          0 :                     bNextToken = sal_False;
     896                 :            :                 }
     897 [ #  # ][ #  # ]:          0 :                 pNew = new CSS1Selector( eType, aElement );
         [ #  # ][ #  # ]
     898                 :            :             }
     899                 :          0 :             break;
     900                 :            :         case CSS1_DOT_W_WS:
     901                 :            :             // DOT_W_WS class
     902                 :            : 
     903                 :            :             // DOT_W_WS
     904                 :          0 :             nToken = GetNextToken();
     905                 :            : 
     906         [ #  # ]:          0 :             if( CSS1_IDENT==nToken )
     907                 :            :             {
     908                 :            :                 // class
     909         [ #  # ]:          0 :                 pNew = new CSS1Selector( CSS1_SELTYPE_CLASS, aToken );
     910                 :            :             }
     911                 :            :             else
     912                 :            :             {
     913                 :            :                 // class fehlt
     914                 :          0 :                 return pRoot;
     915                 :            :             }
     916                 :          0 :             break;
     917                 :            :         case CSS1_HASH:
     918                 :            :             // '#' id_selector
     919                 :            : 
     920                 :            :             // '#'
     921                 :          0 :             nToken = GetNextToken();
     922                 :            : 
     923         [ #  # ]:          0 :             if( CSS1_IDENT==nToken )
     924                 :            :             {
     925                 :            :                 // id_selector
     926         [ #  # ]:          0 :                 pNew = new CSS1Selector( CSS1_SELTYPE_ID, aToken );
     927                 :            :             }
     928                 :            :             else
     929                 :            :             {
     930                 :            :                 // id_selector fehlt
     931                 :          0 :                 return pRoot;
     932                 :            :             }
     933                 :          0 :             break;
     934                 :            : 
     935                 :            : // /Feature: PrintExt
     936                 :            :         case CSS1_PAGE_SYM:
     937                 :            :             {
     938                 :            :                 //  @page
     939         [ #  # ]:          0 :                 pNew = new CSS1Selector( CSS1_SELTYPE_PAGE, aToken );
     940                 :            :             }
     941                 :          0 :             break;
     942                 :            : // /Feature: PrintExt
     943                 :            : 
     944                 :            :         default:
     945                 :            :             // wir wissen nicht was kommt, also aufhoehren
     946                 :          0 :             bDone = sal_True;
     947                 :          0 :             break;
     948                 :            :         }
     949                 :            : 
     950                 :            :         // falls ein Selektor angelegt wurd, ihn speichern
     951         [ #  # ]:          0 :         if( pNew )
     952                 :            :         {
     953                 :            :             OSL_ENSURE( (pRoot!=0) == (pLast!=0),
     954                 :            :                     "Root-Selektor, aber kein Last" );
     955         [ #  # ]:          0 :             if( pLast )
     956                 :          0 :                 pLast->SetNext( pNew );
     957                 :            :             else
     958                 :          0 :                 pRoot = pNew;
     959                 :            : 
     960                 :          0 :             pLast = pNew;
     961                 :          0 :             pNew = 0;
     962                 :            :         }
     963                 :            : 
     964 [ #  # ][ #  # ]:          0 :         if( bNextToken && !bDone )
     965                 :          0 :             nToken = GetNextToken();
     966                 :            :     }
     967                 :            : 
     968         [ #  # ]:          0 :     if( !pRoot )
     969                 :            :     {
     970                 :            :         // simple_selector fehlt
     971                 :          0 :         return pRoot;
     972                 :            :     }
     973                 :            : 
     974                 :            :     // [ ':' pseudo_element ]?
     975 [ #  # ][ #  # ]:          0 :     if( CSS1_COLON==nToken && IsParserWorking() )
                 [ #  # ]
     976                 :            :     {
     977                 :            :         // ':' pseudo element
     978                 :          0 :         nToken = GetNextToken();
     979         [ #  # ]:          0 :         if( CSS1_IDENT==nToken )
     980                 :            :         {
     981         [ #  # ]:          0 :             pLast->SetNext( new CSS1Selector(CSS1_SELTYPE_PSEUDO,aToken) );
     982                 :          0 :             nToken = GetNextToken();
     983                 :            :         }
     984                 :            :         else
     985                 :            :         {
     986                 :            :             // pseudo_element fehlt
     987                 :          0 :             return pRoot;
     988                 :            :         }
     989                 :            :     }
     990                 :            : 
     991                 :          0 :     return pRoot;
     992                 :            : }
     993                 :            : 
     994                 :            : // declaration
     995                 :            : //  : property ':' expr prio?
     996                 :            : //  | /* empty */
     997                 :            : //
     998                 :            : // expression
     999                 :            : //  : term [ operator term ]*
    1000                 :            : //
    1001                 :            : // term
    1002                 :            : //  : unary_operator?
    1003                 :            : //     [ NUMBER | STRING | PERCENTAGE | LENGTH | EMS | EXS | IDENT |
    1004                 :            : //       HEXCOLOR | URL | RGB ]
    1005                 :            : //
    1006                 :            : // operator
    1007                 :            : //  : '/' | ',' | /* empty */
    1008                 :            : //
    1009                 :            : // unary_operator
    1010                 :            : //  : '-' | '+'
    1011                 :            : //
    1012                 :            : // property
    1013                 :            : //  : ident
    1014                 :            : //
    1015                 :            : // das Vorzeichen wird nur fuer numerische Werte (ausser PERCENTAGE)
    1016                 :            : // beruecksichtigt und wird auf nValue angewendet!
    1017                 :          0 : CSS1Expression *CSS1Parser::ParseDeclaration( String& rProperty )
    1018                 :            : {
    1019                 :          0 :     CSS1Expression *pRoot = 0, *pLast = 0;
    1020                 :            : 
    1021                 :            :     // property
    1022         [ #  # ]:          0 :     if( CSS1_IDENT != nToken )
    1023                 :            :     {
    1024                 :            :         // property fehlt
    1025                 :          0 :         return pRoot;
    1026                 :            :     }
    1027                 :          0 :     rProperty = aToken;
    1028                 :            : 
    1029                 :          0 :     nToken = GetNextToken();
    1030                 :            : 
    1031                 :            : 
    1032                 :            :     // ':'
    1033         [ #  # ]:          0 :     if( CSS1_COLON != nToken )
    1034                 :            :     {
    1035                 :            :         // ':' fehlt
    1036                 :          0 :         return pRoot;
    1037                 :            :     }
    1038                 :          0 :     nToken = GetNextToken();
    1039                 :            : 
    1040                 :            :     // term [operator term]*
    1041                 :            :     // hier sind wir sehr lax, was die Syntax angeht, sollte aber kein
    1042                 :            :     // Problem sein
    1043                 :          0 :     sal_Bool bDone = sal_False;
    1044                 :          0 :     sal_Unicode cSign = 0, cOp = 0;
    1045                 :          0 :     CSS1Expression *pNew = 0;
    1046                 :            : 
    1047                 :          0 :     LOOP_CHECK_DECL
    1048                 :            : 
    1049 [ #  # ][ #  # ]:          0 :     while( !bDone && IsParserWorking() )
                 [ #  # ]
    1050                 :            :     {
    1051 [ #  # ][ #  # ]:          0 :         LOOP_CHECK_CHECK( "Endlos-Schleife in ParseDeclaration()" )
    1052                 :            : 
    1053   [ #  #  #  #  :          0 :         switch( nToken )
                #  #  # ]
    1054                 :            :         {
    1055                 :            :         case CSS1_MINUS:
    1056                 :          0 :             cSign = '-';
    1057                 :          0 :             break;
    1058                 :            : 
    1059                 :            :         case CSS1_PLUS:
    1060                 :          0 :             cSign = '+';
    1061                 :          0 :             break;
    1062                 :            : 
    1063                 :            :         case CSS1_NUMBER:
    1064                 :            :         case CSS1_LENGTH:
    1065                 :            :         case CSS1_PIXLENGTH:
    1066                 :            :         case CSS1_EMS:
    1067                 :            :         case CSS1_EMX:
    1068         [ #  # ]:          0 :             if( '-'==cSign )
    1069                 :          0 :                 nValue = -nValue;
    1070                 :            :         case CSS1_STRING:
    1071                 :            :         case CSS1_PERCENTAGE:
    1072                 :            :         case CSS1_IDENT:
    1073                 :            :         case CSS1_URL:
    1074                 :            :         case CSS1_RGB:
    1075                 :            :         case CSS1_HEXCOLOR:
    1076         [ #  # ]:          0 :             pNew = new CSS1Expression( nToken, aToken, nValue, cOp );
    1077                 :          0 :             nValue = 0; // sonst landet das auch im naechsten Ident
    1078                 :          0 :             cSign = 0;
    1079                 :          0 :             cOp = 0;
    1080                 :          0 :             break;
    1081                 :            : 
    1082                 :            :         case CSS1_SLASH:
    1083                 :          0 :             cOp = '/';
    1084                 :          0 :             cSign = 0;
    1085                 :          0 :             break;
    1086                 :            : 
    1087                 :            :         case CSS1_COMMA:
    1088                 :          0 :             cOp = ',';
    1089                 :          0 :             cSign = 0;
    1090                 :          0 :             break;
    1091                 :            : 
    1092                 :            :         default:
    1093                 :          0 :             bDone = sal_True;
    1094                 :          0 :             break;
    1095                 :            :         }
    1096                 :            : 
    1097                 :            :         // falls ein Expression angelegt wurde, diesen speichern
    1098         [ #  # ]:          0 :         if( pNew )
    1099                 :            :         {
    1100                 :            :             OSL_ENSURE( (pRoot!=0) == (pLast!=0),
    1101                 :            :                     "Root-Selektor, aber kein Last" );
    1102         [ #  # ]:          0 :             if( pLast )
    1103                 :          0 :                 pLast->SetNext( pNew );
    1104                 :            :             else
    1105                 :          0 :                 pRoot = pNew;
    1106                 :            : 
    1107                 :          0 :             pLast = pNew;
    1108                 :          0 :             pNew = 0;
    1109                 :            :         }
    1110                 :            : 
    1111         [ #  # ]:          0 :         if( !bDone )
    1112                 :          0 :             nToken = GetNextToken();
    1113                 :            :     }
    1114                 :            : 
    1115         [ #  # ]:          0 :     if( !pRoot )
    1116                 :            :     {
    1117                 :            :         // term fehlt
    1118                 :          0 :         return pRoot;
    1119                 :            :     }
    1120                 :            : 
    1121                 :            :     // prio?
    1122         [ #  # ]:          0 :     if( CSS1_IMPORTANT_SYM==nToken )
    1123                 :            :     {
    1124                 :            :         // IMPORTANT_SYM
    1125                 :          0 :         nToken = GetNextToken();
    1126                 :            :     }
    1127                 :            : 
    1128                 :          0 :     return pRoot;
    1129                 :            : }
    1130                 :            : 
    1131                 :            : 
    1132                 :          2 : CSS1Parser::CSS1Parser()
    1133                 :            :     : nValue(0)
    1134                 :            :     , eState(CSS1_PAR_ACCEPTED)
    1135         [ +  - ]:          2 :     , nToken(CSS1_NULL)
    1136                 :            : {
    1137                 :          2 : }
    1138                 :            : 
    1139         [ +  - ]:          2 : CSS1Parser::~CSS1Parser()
    1140                 :            : {
    1141         [ -  + ]:          2 : }
    1142                 :            : 
    1143                 :            : 
    1144                 :          0 : sal_Bool CSS1Parser::ParseStyleSheet( const String& rIn )
    1145                 :            : {
    1146         [ #  # ]:          0 :     String aTmp( rIn );
    1147                 :            : 
    1148                 :            :     sal_Unicode c;
    1149 [ #  # ][ #  # ]:          0 :     while( aTmp.Len() &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1150                 :            :            ( ' '==(c=aTmp.GetChar(0)) || '\t'==c || '\r'==c || '\n'==c ) )
    1151         [ #  # ]:          0 :         aTmp.Erase( 0, 1 );
    1152                 :            : 
    1153 [ #  # ][ #  # ]:          0 :     while( aTmp.Len() && ( ' '==(c=aTmp.GetChar( aTmp.Len()-1))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1154                 :            :            || '\t'==c || '\r'==c || '\n'==c ) )
    1155         [ #  # ]:          0 :         aTmp.Erase( aTmp.Len()-1 );
    1156                 :            : 
    1157                 :            :     // SGML-Kommentare entfernen
    1158 [ #  # ][ #  # ]:          0 :     if( aTmp.Len() >= 4 &&
                 [ #  # ]
    1159         [ #  # ]:          0 :         aTmp.CompareToAscii("<!--",4) == COMPARE_EQUAL )
    1160         [ #  # ]:          0 :         aTmp.Erase( 0, 4 );
    1161                 :            : 
    1162 [ #  # ][ #  # ]:          0 :     if( aTmp.Len() >=3 &&
                 [ #  # ]
    1163 [ #  # ][ #  # ]:          0 :         aTmp.Copy(aTmp.Len()-3).CompareToAscii("-->") == COMPARE_EQUAL )
         [ #  # ][ #  # ]
                 [ #  # ]
    1164         [ #  # ]:          0 :         aTmp.Erase( aTmp.Len()-3 );
    1165                 :            : 
    1166         [ #  # ]:          0 :     if( !aTmp.Len() )
    1167                 :          0 :         return sal_True;
    1168                 :            : 
    1169         [ #  # ]:          0 :     InitRead( aTmp );
    1170                 :            : 
    1171         [ #  # ]:          0 :     ParseStyleSheet();
    1172                 :            : 
    1173         [ #  # ]:          0 :     return sal_True;
    1174                 :            : }
    1175                 :            : 
    1176                 :            : 
    1177                 :          0 : sal_Bool CSS1Parser::ParseStyleOption( const String& rIn )
    1178                 :            : {
    1179         [ #  # ]:          0 :     if( !rIn.Len() )
    1180                 :          0 :         return sal_True;
    1181                 :            : 
    1182         [ #  # ]:          0 :     InitRead( rIn );
    1183                 :            : 
    1184                 :            :     // fdo#41796: skip over spurious semicolons
    1185         [ #  # ]:          0 :     while (CSS1_SEMICOLON == nToken)
    1186                 :            :     {
    1187         [ #  # ]:          0 :         nToken = GetNextToken();
    1188                 :            :     }
    1189                 :            : 
    1190         [ #  # ]:          0 :     String aProperty;
    1191         [ #  # ]:          0 :     CSS1Expression *pExpr = ParseDeclaration( aProperty );
    1192         [ #  # ]:          0 :     if( !pExpr )
    1193                 :            :     {
    1194                 :          0 :         return sal_False;
    1195                 :            :     }
    1196                 :            : 
    1197                 :            :     // expression verarbeiten
    1198 [ #  # ][ #  # ]:          0 :     if( DeclarationParsed( aProperty, pExpr ) )
    1199 [ #  # ][ #  # ]:          0 :         delete pExpr;
    1200                 :            : 
    1201                 :          0 :     LOOP_CHECK_DECL
    1202                 :            : 
    1203                 :            :     // [ ';' declaration ]*
    1204 [ #  # ][ #  # ]:          0 :     while( CSS1_SEMICOLON==nToken && IsParserWorking() )
                 [ #  # ]
    1205                 :            :     {
    1206 [ #  # ][ #  # ]:          0 :         LOOP_CHECK_CHECK( "Endlos-Schleife in ParseStyleOption()" )
    1207                 :            : 
    1208         [ #  # ]:          0 :         nToken = GetNextToken();
    1209         [ #  # ]:          0 :         if( CSS1_IDENT==nToken )
    1210                 :            :         {
    1211         [ #  # ]:          0 :             CSS1Expression *pExp = ParseDeclaration( aProperty );
    1212         [ #  # ]:          0 :             if( pExp )
    1213                 :            :             {
    1214                 :            :                 // expression verarbeiten
    1215 [ #  # ][ #  # ]:          0 :                 if( DeclarationParsed( aProperty, pExp ) )
    1216 [ #  # ][ #  # ]:          0 :                     delete pExp;
    1217                 :            :             }
    1218                 :            :         }
    1219                 :            :     }
    1220                 :            : 
    1221         [ #  # ]:          0 :     return sal_True;
    1222                 :            : }
    1223                 :            : 
    1224                 :          0 : bool CSS1Parser::SelectorParsed( CSS1Selector* /* pSelector */, bool /*bFirst*/ )
    1225                 :            : {
    1226                 :            :     // Selektor loeschen
    1227                 :          0 :     return true;
    1228                 :            : }
    1229                 :            : 
    1230                 :          0 : sal_Bool CSS1Parser::DeclarationParsed( const String& /*rProperty*/,
    1231                 :            :                                     const CSS1Expression * /* pExpr */ )
    1232                 :            : {
    1233                 :            :     // Deklaration loeschen
    1234                 :          0 :     return sal_True;
    1235                 :            : }
    1236                 :            : 
    1237                 :            : 
    1238                 :          0 : CSS1Selector::~CSS1Selector()
    1239                 :            : {
    1240 [ #  # ][ #  # ]:          0 :     delete pNext;
    1241                 :          0 : }
    1242                 :            : 
    1243                 :          0 : CSS1Expression::~CSS1Expression()
    1244                 :            : {
    1245 [ #  # ][ #  # ]:          0 :     delete pNext;
    1246                 :          0 : }
    1247                 :            : 
    1248                 :          0 : sal_Bool CSS1Expression::GetURL( String& rURL  ) const
    1249                 :            : {
    1250                 :            :     OSL_ENSURE( CSS1_URL==eType, "CSS1-Ausruck ist keine Farbe URL" );
    1251                 :            : 
    1252                 :            :     OSL_ENSURE( aValue.CompareIgnoreCaseToAscii( sCSS1_url, 3 ) ==
    1253                 :            :                                         COMPARE_EQUAL &&
    1254                 :            :                 aValue.Len() > 5 &&
    1255                 :            :                 '(' == aValue.GetChar(3) &&
    1256                 :            :                 ')' == aValue.GetChar(aValue.Len()-1),
    1257                 :            :                 "keine gueltiges URL(...)" );
    1258                 :            : 
    1259                 :          0 :     sal_Bool bRet = sal_False;
    1260                 :            : 
    1261         [ #  # ]:          0 :     if( aValue.Len() > 5 )
    1262                 :            :     {
    1263         [ #  # ]:          0 :         rURL = aValue.Copy( 4, aValue.Len()-5 );
    1264 [ #  # ][ #  # ]:          0 :         rURL = comphelper::string::strip(rURL, ' ');
    1265                 :          0 :         bRet = sal_True;
    1266                 :            :     }
    1267                 :            : 
    1268                 :          0 :     return bRet;
    1269                 :            : }
    1270                 :            : 
    1271                 :          0 : sal_Bool CSS1Expression::GetColor( Color &rColor ) const
    1272                 :            : {
    1273                 :            :     OSL_ENSURE( CSS1_IDENT==eType || CSS1_RGB==eType ||
    1274                 :            :                 CSS1_HEXCOLOR==eType || CSS1_STRING==eType,
    1275                 :            :                 "CSS1-Ausruck kann keine Farbe sein" );
    1276                 :            : 
    1277                 :          0 :     sal_Bool bRet = sal_False;
    1278                 :          0 :     sal_uInt32 nColor = SAL_MAX_UINT32;
    1279                 :            : 
    1280   [ #  #  #  # ]:          0 :     switch( eType )
    1281                 :            :     {
    1282                 :            :     case CSS1_RGB:
    1283                 :            :         {
    1284                 :          0 :             sal_uInt8 aColors[3] = { 0, 0, 0 };
    1285                 :            : 
    1286                 :            :             OSL_ENSURE( aValue.CompareIgnoreCaseToAscii( sCSS1_rgb, 3 )
    1287                 :            :                                             == COMPARE_EQUAL &&
    1288                 :            :                         aValue.Len() > 5 &&
    1289                 :            :                         '(' == aValue.GetChar( 3 ) &&
    1290                 :            :                         ')' == aValue.GetChar( aValue.Len()-1),
    1291                 :            :                         "keine gueltiges RGB(...)" );
    1292                 :            : 
    1293         [ #  # ]:          0 :             String aColorStr( aValue.Copy( 4, aValue.Len()-1 ) );
    1294                 :            : 
    1295                 :          0 :             xub_StrLen nPos = 0;
    1296                 :          0 :             sal_uInt16 nCol = 0;
    1297                 :            : 
    1298 [ #  # ][ #  # ]:          0 :             while( nCol < 3 && nPos < aColorStr.Len() )
                 [ #  # ]
    1299                 :            :             {
    1300                 :            :                 sal_Unicode c;
    1301 [ #  # ][ #  # ]:          0 :                 while( nPos < aColorStr.Len() &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1302                 :          0 :                         ((c=aColorStr.GetChar(nPos)) == ' ' || c == '\t' ||
    1303                 :            :                         c == '\n' || c== '\r' ) )
    1304                 :          0 :                     nPos++;
    1305                 :            : 
    1306         [ #  # ]:          0 :                 xub_StrLen nEnd = aColorStr.Search( ',', nPos );
    1307         [ #  # ]:          0 :                 String aNumber;
    1308         [ #  # ]:          0 :                 if( STRING_NOTFOUND==nEnd )
    1309                 :            :                 {
    1310 [ #  # ][ #  # ]:          0 :                     aNumber = aColorStr.Copy(nPos);
                 [ #  # ]
    1311                 :          0 :                     nPos = aColorStr.Len();
    1312                 :            :                 }
    1313                 :            :                 else
    1314                 :            :                 {
    1315 [ #  # ][ #  # ]:          0 :                     aNumber = aColorStr.Copy( nPos, nEnd-nPos );
                 [ #  # ]
    1316                 :          0 :                     nPos = nEnd+1;
    1317                 :            :                 }
    1318                 :            : 
    1319         [ #  # ]:          0 :                 sal_uInt16 nNumber = (sal_uInt16)aNumber.ToInt32();
    1320 [ #  # ][ #  # ]:          0 :                 if( aNumber.Search('%') != STRING_NOTFOUND )
    1321                 :            :                 {
    1322         [ #  # ]:          0 :                     if( nNumber > 100 )
    1323                 :          0 :                         nNumber = 100;
    1324                 :          0 :                     nNumber *= 255;
    1325                 :          0 :                     nNumber /= 100;
    1326                 :            :                 }
    1327         [ #  # ]:          0 :                 else if( nNumber > 255 )
    1328                 :          0 :                     nNumber = 255;
    1329                 :            : 
    1330                 :          0 :                 aColors[nCol] = (sal_uInt8)nNumber;
    1331                 :          0 :                 nCol ++;
    1332         [ #  # ]:          0 :             }
    1333                 :            : 
    1334         [ #  # ]:          0 :             rColor.SetRed( aColors[0] );
    1335         [ #  # ]:          0 :             rColor.SetGreen( aColors[1] );
    1336         [ #  # ]:          0 :             rColor.SetBlue( aColors[2] );
    1337                 :            : 
    1338         [ #  # ]:          0 :             bRet = sal_True;    // etwas anderes als eine Farbe kann es nicht sein
    1339                 :            :         }
    1340                 :          0 :         break;
    1341                 :            : 
    1342                 :            :     case CSS1_IDENT:
    1343                 :            :     case CSS1_STRING:
    1344                 :            :         {
    1345         [ #  # ]:          0 :             String aTmp( aValue );
    1346         [ #  # ]:          0 :             aTmp.ToUpperAscii();
    1347         [ #  # ]:          0 :             nColor = GetHTMLColor( aTmp );
    1348         [ #  # ]:          0 :             bRet = nColor != SAL_MAX_UINT32;
    1349                 :            :         }
    1350 [ #  # ][ #  # ]:          0 :         if( bRet || CSS1_STRING != eType || !aValue.Len() ||
           [ #  #  #  # ]
                 [ #  # ]
    1351                 :          0 :             aValue.GetChar( 0 )!='#' )
    1352                 :          0 :             break;
    1353                 :            : 
    1354                 :            :     case CSS1_HEXCOLOR:
    1355                 :            :         {
    1356                 :            :             // HACK fuer MS-IE: DIe Farbe kann auch in einem String stehen
    1357         [ #  # ]:          0 :             xub_StrLen nOffset = CSS1_STRING==eType ? 1 : 0;
    1358                 :          0 :             sal_Bool bDouble = aValue.Len()-nOffset == 3;
    1359         [ #  # ]:          0 :             xub_StrLen i = nOffset, nEnd = (bDouble ? 3 : 6) + nOffset;
    1360                 :            : 
    1361                 :          0 :             nColor = 0;
    1362         [ #  # ]:          0 :             for( ; i<nEnd; i++ )
    1363                 :            :             {
    1364                 :          0 :                 sal_Unicode c = (i<aValue.Len() ? aValue.GetChar(i)
    1365         [ #  # ]:          0 :                                                          : '0' );
    1366 [ #  # ][ #  # ]:          0 :                 if( c >= '0' && c <= '9' )
    1367                 :          0 :                     c -= 48;
    1368 [ #  # ][ #  # ]:          0 :                 else if( c >= 'A' && c <= 'F' )
    1369                 :          0 :                     c -= 55;
    1370 [ #  # ][ #  # ]:          0 :                 else if( c >= 'a' && c <= 'f' )
    1371                 :          0 :                     c -= 87;
    1372                 :            :                 else
    1373                 :          0 :                     c = 16;
    1374                 :            : 
    1375                 :          0 :                 nColor *= 16;
    1376         [ #  # ]:          0 :                 if( c<16 )
    1377                 :          0 :                     nColor += c;
    1378         [ #  # ]:          0 :                 if( bDouble )
    1379                 :            :                 {
    1380                 :          0 :                     nColor *= 16;
    1381         [ #  # ]:          0 :                     if( c<16 )
    1382                 :          0 :                         nColor += c;
    1383                 :            :                 }
    1384                 :            :             }
    1385                 :          0 :             bRet = sal_True;
    1386                 :            :         }
    1387                 :          0 :         break;
    1388                 :            :     default:
    1389                 :            :         ;
    1390                 :            :     }
    1391                 :            : 
    1392                 :            : 
    1393 [ #  # ][ #  # ]:          0 :     if( bRet && nColor!=SAL_MAX_UINT32 )
    1394                 :            :     {
    1395                 :          0 :         rColor.SetRed( (sal_uInt8)((nColor & 0x00ff0000UL) >> 16) );
    1396                 :          0 :         rColor.SetGreen( (sal_uInt8)((nColor & 0x0000ff00UL) >> 8) );
    1397                 :          0 :         rColor.SetBlue( (sal_uInt8)(nColor & 0x000000ffUL) );
    1398                 :            :     }
    1399                 :            : 
    1400                 :          0 :     return bRet;
    1401                 :            : }
    1402                 :            : 
    1403                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10