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

Generated by: LCOV version 1.10