LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/filter/html - parcss1.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 6 617 1.0 %
Date: 2013-07-09 Functions: 4 20 20.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10