LCOV - code coverage report
Current view: top level - libreoffice/filter/source/flash - swfwriter2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 299 0.0 %
Date: 2012-12-27 Functions: 0 39 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 "swfwriter.hxx"
      21             : #include <vcl/virdev.hxx>
      22             : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      23             : 
      24             : #include <math.h>
      25             : 
      26             : using namespace ::swf;
      27             : using namespace ::std;
      28             : using namespace ::com::sun::star::uno;
      29             : using namespace ::com::sun::star::io;
      30             : using ::rtl::OUString;
      31             : using ::rtl::OString;
      32             : 
      33             : // -----------------------------------------------------------------------------
      34             : 
      35           0 : sal_uInt16 getMaxBitsUnsigned( sal_uInt32 nValue )
      36             : {
      37           0 :     sal_uInt16 nBits = 0;
      38             : 
      39           0 :     while( nValue )
      40             :     {
      41           0 :         nBits++;
      42           0 :         nValue >>= 1;
      43             :     }
      44             : 
      45           0 :     return nBits;
      46             : }
      47             : 
      48             : // -----------------------------------------------------------------------------
      49             : 
      50           0 : sal_uInt16 getMaxBitsSigned( sal_Int32 nValue )
      51             : {
      52           0 :     if( nValue < 0 )
      53           0 :         nValue *= -1;
      54             : 
      55           0 :     return getMaxBitsUnsigned( static_cast< sal_uInt32 >(nValue) ) + 1;
      56             : }
      57             : 
      58             : // -----------------------------------------------------------------------------
      59             : 
      60           0 : BitStream::BitStream()
      61             : {
      62           0 :     mnBitPos = 8;
      63           0 :     mnCurrentByte = 0;
      64           0 : }
      65             : 
      66             : // -----------------------------------------------------------------------------
      67             : 
      68           0 : void BitStream::writeUB( sal_uInt32 nValue, sal_uInt16 nBits )
      69             : {
      70           0 :     while( nBits != 0 )
      71             :     {
      72           0 :         mnCurrentByte |= nValue << (32 - nBits) >> (32 - mnBitPos);
      73             : 
      74           0 :         if ( nBits > mnBitPos )
      75             :         {
      76           0 :             nBits = nBits - mnBitPos;
      77           0 :             mnBitPos = 0;
      78             :         }
      79             :         else
      80             :         {
      81           0 :             mnBitPos = sal::static_int_cast<sal_uInt8>( mnBitPos - nBits );
      82           0 :             nBits = 0;
      83             :         }
      84             : 
      85           0 :         if( 0 == mnBitPos )
      86           0 :             pad();
      87             :     }
      88           0 : }
      89             : 
      90             : // -----------------------------------------------------------------------------
      91             : 
      92           0 : void BitStream::writeSB( sal_Int32 nValue, sal_uInt16 nBits )
      93             : {
      94           0 :     writeUB( static_cast< sal_uInt32 >(nValue), nBits );
      95           0 : }
      96             : 
      97             : // -----------------------------------------------------------------------------
      98             : 
      99           0 : void BitStream::writeFB( sal_uInt32 nValue, sal_uInt16 nBits )
     100             : {
     101           0 :     writeUB( nValue, nBits );
     102           0 : }
     103             : 
     104             : // -----------------------------------------------------------------------------
     105             : 
     106           0 : void BitStream::pad()
     107             : {
     108           0 :     if( 8 != mnBitPos )
     109             :     {
     110           0 :         maData.push_back( mnCurrentByte );
     111           0 :         mnCurrentByte = 0;
     112           0 :         mnBitPos = 8;
     113             :     }
     114           0 : }
     115             : 
     116             : // -----------------------------------------------------------------------------
     117             : 
     118           0 : void BitStream::writeTo( SvStream& out )
     119             : {
     120           0 :     pad();
     121             : 
     122           0 :     vector< sal_uInt8 >::iterator aIter( maData.begin() );
     123           0 :     const vector< sal_uInt8>::iterator aEnd( maData.end() );
     124           0 :     while(aIter != aEnd)
     125             :     {
     126           0 :         out << (*aIter++);
     127             :     }
     128           0 : }
     129             : 
     130             : // -----------------------------------------------------------------------------
     131             : 
     132           0 : sal_uInt32 BitStream::getOffset() const
     133             : {
     134           0 :     return maData.size();
     135             : }
     136             : 
     137             : ////////////////////////////////////////////////////////////////////////////////
     138             : 
     139           0 : Tag::Tag( sal_uInt8 nTagId )
     140             : {
     141           0 :     mnTagId = nTagId;
     142           0 : }
     143             : 
     144             : // -----------------------------------------------------------------------------
     145             : 
     146           0 : void Tag::write( SvStream &out )
     147             : {
     148           0 :     Seek( STREAM_SEEK_TO_END );
     149           0 :     sal_uInt32 nSz = Tell();
     150           0 :     Seek( STREAM_SEEK_TO_BEGIN );
     151             : 
     152           0 :     if( mnTagId != 0xff )
     153             :     {
     154           0 :         bool bLarge = nSz > 62;
     155             : 
     156           0 :         sal_uInt16 nCode = ( mnTagId << 6 ) | ( bLarge ? 0x3f : _uInt16(nSz) );
     157             : 
     158           0 :         out << (sal_uInt8)nCode;
     159           0 :         out << (sal_uInt8)(nCode >> 8);
     160             : 
     161           0 :         if( bLarge )
     162             :         {
     163           0 :             sal_uInt32 nTmp = nSz;
     164             : 
     165           0 :             out << (sal_uInt8)nTmp;
     166           0 :             nTmp >>= 8;
     167           0 :             out << (sal_uInt8)nTmp;
     168           0 :             nTmp >>= 8;
     169           0 :             out << (sal_uInt8)nTmp;
     170           0 :             nTmp >>= 8;
     171           0 :             out << (sal_uInt8)nTmp;
     172             :         }
     173             :     }
     174             : 
     175           0 :     out.Write( GetData(), nSz );
     176           0 : }
     177             : #if 0
     178             : // -----------------------------------------------------------------------------
     179             : 
     180             : void Tag::addI32( sal_Int32 nValue )
     181             : {
     182             :     addUI32( static_cast<sal_uInt32>( nValue ) );
     183             : }
     184             : #endif
     185             : // -----------------------------------------------------------------------------
     186             : 
     187           0 : void Tag::addUI32( sal_uInt32 nValue )
     188             : {
     189           0 :     *this << nValue;
     190           0 : }
     191             : #if 0
     192             : // -----------------------------------------------------------------------------
     193             : 
     194             : void Tag::addI16( sal_Int16 nValue )
     195             : {
     196             :     addUI16( static_cast<sal_uInt16>( nValue ) );
     197             : }
     198             : #endif
     199             : // -----------------------------------------------------------------------------
     200             : 
     201           0 : void Tag::addUI16( sal_uInt16 nValue )
     202             : {
     203           0 :     *this << (sal_uInt8)nValue;
     204           0 :     *this << (sal_uInt8)(nValue >> 8);
     205           0 : }
     206             : 
     207             : // -----------------------------------------------------------------------------
     208             : 
     209           0 : void Tag::addUI8( sal_uInt8 nValue )
     210             : {
     211           0 :     *this << (sal_uInt8)nValue;
     212           0 : }
     213             : 
     214             : // -----------------------------------------------------------------------------
     215             : 
     216           0 : void Tag::addBits( BitStream& rIn )
     217             : {
     218           0 :     rIn.writeTo( *this );
     219           0 : }
     220             : 
     221             : // -----------------------------------------------------------------------------
     222             : 
     223           0 : void Tag::addRGBA( const Color& rColor )
     224             : {
     225           0 :     addUI8( rColor.GetRed() );
     226           0 :     addUI8( rColor.GetGreen() );
     227           0 :     addUI8( rColor.GetBlue() );
     228           0 :     addUI8( 0xff - rColor.GetTransparency() );
     229           0 : }
     230             : 
     231             : // -----------------------------------------------------------------------------
     232             : 
     233           0 : void Tag::addRGB( const Color& rColor )
     234             : {
     235           0 :     addUI8( rColor.GetRed() );
     236           0 :     addUI8( rColor.GetGreen() );
     237           0 :     addUI8( rColor.GetBlue() );
     238           0 : }
     239             : 
     240             : // -----------------------------------------------------------------------------
     241             : 
     242           0 : void Tag::addRect( const Rectangle& rRect )
     243             : {
     244           0 :     writeRect( *this, rRect );
     245           0 : }
     246             : 
     247             : // -----------------------------------------------------------------------------
     248             : 
     249           0 : void Tag::writeRect( SvStream& rOut, const Rectangle& rRect )
     250             : {
     251           0 :     BitStream aBits;
     252             : 
     253             :     sal_Int32 minX, minY, maxX, maxY;
     254             : 
     255           0 :     if( rRect.Left() < rRect.Right() )
     256             :     {
     257           0 :         minX = rRect.Left();
     258           0 :         maxX = rRect.Right();
     259             :     }
     260             :     else
     261             :     {
     262           0 :         maxX = rRect.Left();
     263           0 :         minX = rRect.Right();
     264             :     }
     265             : 
     266             : 
     267           0 :     if( rRect.Top() < rRect.Bottom() )
     268             :     {
     269           0 :         minY = rRect.Top();
     270           0 :         maxY = rRect.Bottom();
     271             :     }
     272             :     else
     273             :     {
     274           0 :         maxY = rRect.Top();
     275           0 :         minY = rRect.Bottom();
     276             :     }
     277             : 
     278             :     // AS: Figure out the maximum nubmer of bits required to represent any of the
     279             :     //  rectangle coordinates.  Since minX or minY could be negative, they could
     280             :     //  actually require more bits than maxX or maxY.
     281             :     // AS: Christian, can they be negative, or is that a wasted check?
     282             :     // CL: I think so, f.e. for shapes that have the top and/or left edge outside
     283             :     //         the page origin
     284           0 :     sal_uInt8 nBits1 = sal::static_int_cast<sal_uInt8>( max( getMaxBitsSigned( minX ), getMaxBitsSigned( minY ) ) );
     285           0 :     sal_uInt8 nBits2 = sal::static_int_cast<sal_uInt8>( max( getMaxBitsSigned( maxX ), getMaxBitsSigned( maxY ) ) );
     286           0 :     sal_uInt8 nBitsMax = max( nBits1, nBits2 );
     287             : 
     288           0 :     aBits.writeUB( nBitsMax, 5 );
     289           0 :     aBits.writeSB( minX, nBitsMax );
     290           0 :     aBits.writeSB( maxX, nBitsMax );
     291           0 :     aBits.writeSB( minY, nBitsMax );
     292           0 :     aBits.writeSB( maxY, nBitsMax );
     293             : 
     294           0 :     aBits.writeTo( rOut );
     295           0 : }
     296             : 
     297             : // -----------------------------------------------------------------------------
     298             : 
     299           0 : void Tag::addMatrix( const ::basegfx::B2DHomMatrix& rMatrix ) // #i73264#
     300             : {
     301           0 :     writeMatrix( *this, rMatrix );
     302           0 : }
     303             : 
     304             : // -----------------------------------------------------------------------------
     305             : 
     306           0 : void Tag::writeMatrix( SvStream& rOut, const ::basegfx::B2DHomMatrix& rMatrix ) // #i73264#
     307             : {
     308             : 
     309           0 :     BitStream aBits;
     310             : 
     311           0 :     const sal_uInt8 bHasScale = rMatrix.get(0, 0) != 1.0 || rMatrix.get(1, 1) != 1.0;
     312             : 
     313           0 :     aBits.writeUB( bHasScale, 1 );
     314             : 
     315           0 :     if( bHasScale )
     316             :     {
     317           0 :         sal_uInt8 nScaleBits = 31;
     318             : 
     319           0 :         aBits.writeUB( nScaleBits, 5 );
     320           0 :         aBits.writeFB( getFixed( rMatrix.get(0, 0) ), nScaleBits ); // Scale X
     321           0 :         aBits.writeFB( getFixed( rMatrix.get(1, 1) ), nScaleBits ); // Scale Y
     322             :     }
     323             : 
     324           0 :     const sal_uInt8 bHasRotate = rMatrix.get(0, 1) != 0.0 || rMatrix.get(1, 0) != 0.0;
     325             : 
     326           0 :     aBits.writeUB( bHasRotate, 1 );
     327             : 
     328           0 :     if( bHasRotate )
     329             :     {
     330           0 :         sal_uInt8 nRotateBits = 31;
     331             : 
     332           0 :         aBits.writeUB( nRotateBits, 5 );
     333           0 :         aBits.writeFB( getFixed( rMatrix.get(0, 1) ), nRotateBits );    // RotateSkew0
     334           0 :         aBits.writeFB( getFixed( rMatrix.get(1, 0) ), nRotateBits );    // RotateSkew1
     335             :     }
     336             : 
     337           0 :     sal_uInt8 nTranslateBits = 16;
     338             : 
     339           0 :     aBits.writeUB( nTranslateBits, 5 );
     340           0 :     aBits.writeSB( (sal_Int16)rMatrix.get(0, 2), nTranslateBits );      // Translate X
     341           0 :     aBits.writeSB( (sal_Int16)rMatrix.get(1, 2), nTranslateBits );      // Translate Y
     342             : 
     343           0 :     aBits.writeTo( rOut );
     344           0 : }
     345             : 
     346             : // -----------------------------------------------------------------------------
     347             : 
     348           0 : void Tag::addString( const char* pString )
     349             : {
     350           0 :     if( pString )
     351             :     {
     352           0 :         while( *pString )
     353           0 :             addUI8( *pString++ );
     354             :     }
     355             : 
     356           0 :     addUI8( 0 );
     357           0 : }
     358             : 
     359             : // -----------------------------------------------------------------------------
     360             : 
     361           0 : void Tag::addStream( SvStream& rIn )
     362             : {
     363           0 :     *this << rIn;
     364           0 : }
     365             : 
     366             : ////////////////////////////////////////////////////////////////////////////////
     367             : 
     368           0 : Sprite::Sprite( sal_uInt16 nId )
     369           0 : : mnId( nId ), mnFrames(0)
     370             : {
     371           0 : }
     372             : 
     373             : // -----------------------------------------------------------------------------
     374             : 
     375           0 : Sprite::~Sprite()
     376             : {
     377           0 :     for(vector< Tag* >::iterator i = maTags.begin(); i != maTags.end(); ++i)
     378           0 :         delete *i;
     379           0 : }
     380             : 
     381             : // -----------------------------------------------------------------------------
     382             : 
     383           0 : void Sprite::write( SvStream& out )
     384             : {
     385           0 :     SvMemoryStream aTmp;
     386           0 :     for(vector< Tag* >::iterator i = maTags.begin(); i != maTags.end(); ++i)
     387           0 :         (*i)->write( aTmp );
     388             : 
     389           0 :     if( !mnFrames )
     390           0 :         mnFrames = 1;
     391             : 
     392           0 :     aTmp.Seek(0);
     393             : 
     394           0 :     Tag aTag( TAG_DEFINESPRITE );
     395           0 :     aTag.addUI16( mnId );
     396           0 :     aTag.addUI16( _uInt16( mnFrames ) );
     397           0 :     aTag.addStream( aTmp );
     398           0 :     aTag.write( out );
     399           0 : }
     400             : 
     401             : // -----------------------------------------------------------------------------
     402             : 
     403           0 : void Sprite::addTag( Tag* pNewTag )
     404             : {
     405           0 :     if( pNewTag )
     406             :     {
     407           0 :         if( pNewTag->getTagId() == TAG_SHOWFRAME )
     408           0 :             mnFrames++;
     409             : 
     410           0 :         maTags.push_back( pNewTag );
     411             :     }
     412           0 : }
     413             : 
     414             : /////////////////////////////////////////////////////////////////////////////////
     415             : 
     416           0 : sal_uInt32 swf::getFixed( double fValue )
     417             : {
     418           0 :     sal_Int16 nUpper = (sal_Int16)floor(fValue);
     419           0 :     sal_uInt16 nLower = (sal_uInt16)((fValue - floor(fValue))*0x10000);
     420             : 
     421           0 :     sal_uInt32 temp = ((sal_Int32)nUpper)<<16;
     422           0 :     temp |= nLower;
     423             : 
     424           0 :     return temp;
     425             : }
     426             : 
     427             : /////////////////////////////////////////////////////////////////////////////////
     428             : 
     429             : /** constructs a new flash font for the given VCL Font */
     430           0 : FlashFont::FlashFont( const Font& rFont, sal_uInt16 nId )
     431           0 : : maFont( rFont ), mnNextIndex(0), mnId( nId )
     432             : {
     433           0 : }
     434             : 
     435             : // -----------------------------------------------------------------------------
     436             : 
     437           0 : FlashFont::~FlashFont()
     438             : {
     439           0 : }
     440             : 
     441             : // -----------------------------------------------------------------------------
     442             : 
     443             : /** gets the glyph id for the given character. The glyphs are created on demand */
     444           0 : sal_uInt16 FlashFont::getGlyph( sal_uInt16 nChar, VirtualDevice* pVDev )
     445             : {
     446             :     // see if we already created a glyph for this character
     447           0 :     std::map<sal_uInt16, sal_uInt16, ltuint16>::iterator aIter( maGlyphIndex.find(nChar) );
     448           0 :     if( aIter != maGlyphIndex.end() )
     449             :     {
     450           0 :         return aIter->second;
     451             :     }
     452             : 
     453             :     // if not, we create one now
     454             : 
     455           0 :     maGlyphIndex[nChar] = mnNextIndex;
     456             : 
     457           0 :     Font aOldFont( pVDev->GetFont() );
     458           0 :     Font aNewFont( aOldFont );
     459           0 :     aNewFont.SetAlign( ALIGN_BASELINE );
     460           0 :     pVDev->SetFont( aNewFont );
     461           0 :     aOldFont.SetOrientation(0);
     462             : 
     463             :     // let the virtual device convert the character to polygons
     464           0 :     PolyPolygon aPolyPoly;
     465           0 :     pVDev->GetTextOutline( aPolyPoly, rtl::OUString(nChar) );
     466             : 
     467           0 :     maGlyphOffsets.push_back( _uInt16( maGlyphData.getOffset() ) );
     468             : 
     469             :     // Number of fill and line index bits set to 1
     470           0 :     maGlyphData.writeUB( 0x11, 8 );
     471             : 
     472           0 :     const sal_uInt16 nCount = aPolyPoly.Count();
     473             :     sal_uInt16 i,n;
     474           0 :     for( i = 0; i < nCount; i++ )
     475             :     {
     476           0 :         Polygon& rPoly = aPolyPoly[ i ];
     477             : 
     478           0 :         const sal_uInt16 nSize = rPoly.GetSize();
     479           0 :         if( nSize )
     480             :         {
     481             :             // convert polygon to flash EM_SQUARE (1024x1024)
     482           0 :             for( n = 0; n < nSize; n++ )
     483             :             {
     484           0 :                 Point aPoint( rPoly[n] );
     485           0 :                 aPoint.X() = static_cast<long>((double(aPoint.X()) * 1024.0 ) / double(aOldFont.GetHeight()));
     486           0 :                 aPoint.Y() = static_cast<long>((double(aPoint.Y()) * 1024.0 ) / double(aOldFont.GetHeight()));
     487           0 :                 rPoly[n] = aPoint;
     488             :             }
     489           0 :             Writer::Impl_addPolygon( maGlyphData, rPoly, true );
     490             :         }
     491             :     }
     492           0 :     Writer::Impl_addEndShapeRecord( maGlyphData );
     493             : 
     494           0 :     maGlyphData.pad();
     495             : 
     496           0 :     pVDev->SetFont( aOldFont );
     497             : 
     498           0 :     return mnNextIndex++;
     499             : }
     500             : 
     501             : // -----------------------------------------------------------------------------
     502             : 
     503           0 : void FlashFont::write( SvStream& out )
     504             : {
     505           0 :     Tag aTag( TAG_DEFINEFONT );
     506             : 
     507           0 :     aTag.addUI16( mnId );
     508             : 
     509           0 :     sal_uInt16 nGlyphs = _uInt16( maGlyphOffsets.size() );
     510           0 :     sal_uInt16 nOffset = nGlyphs * sizeof( sal_uInt16 );
     511             : 
     512           0 :     for(vector< sal_uInt16 >::iterator i = maGlyphOffsets.begin(); i != maGlyphOffsets.end(); ++i)
     513           0 :         aTag.addUI16( nOffset + (*i) );
     514             : 
     515           0 :     aTag.addBits( maGlyphData );
     516             : 
     517           0 :     aTag.write( out );
     518           0 : }
     519             : 
     520             : ////////////////////////////////////////////////////////////////////////////////
     521             : 
     522             : /** this c'tor creates a solid fill style */
     523           0 : FillStyle::FillStyle( const Color& rSolidColor )
     524             : :   meType( solid ),
     525           0 :     maColor( rSolidColor )
     526             : {
     527           0 : }
     528             : 
     529             : // -----------------------------------------------------------------------------
     530             : 
     531             : /** this c'tor creates a tiled or clipped bitmap fill style */
     532           0 : FillStyle::FillStyle( sal_uInt16 nBitmapId, bool bClipped, const ::basegfx::B2DHomMatrix& rMatrix ) // #i73264#
     533             : :   meType( bClipped ? clipped_bitmap : tiled_bitmap ),
     534             :     maMatrix( rMatrix ),
     535           0 :     mnBitmapId( nBitmapId )
     536             : {
     537           0 : }
     538             : 
     539             : // -----------------------------------------------------------------------------
     540             : 
     541           0 : FillStyle::FillStyleType Impl_getFillStyleType( const Gradient& rGradient )
     542             : {
     543           0 :     switch( rGradient.GetStyle() )
     544             :     {
     545             :     case GradientStyle_ELLIPTICAL:
     546             :     case GradientStyle_RADIAL:
     547           0 :         return FillStyle::radial_gradient;
     548             : //  case GradientStyle_AXIAL:
     549             : //  case GradientStyle_SQUARE:
     550             : //  case GradientStyle_RECT:
     551             : //  case GradientStyle_LINEAR:
     552             :     default:
     553           0 :         return FillStyle::linear_gradient;
     554             :     }
     555             : }
     556             : 
     557             : // -----------------------------------------------------------------------------
     558             : 
     559             : /** this c'tor creates a linear or radial gradient fill style */
     560           0 : FillStyle::FillStyle( const Rectangle& rBoundRect, const Gradient& rGradient )
     561           0 : :   meType( Impl_getFillStyleType( rGradient ) ),
     562             :     maGradient( rGradient ),
     563           0 :     maBoundRect( rBoundRect )
     564             : {
     565           0 : }
     566             : 
     567             : // -----------------------------------------------------------------------------
     568             : 
     569           0 : void FillStyle::addTo( Tag* pTag ) const
     570             : {
     571           0 :     pTag->addUI8( sal::static_int_cast<sal_uInt8>( meType ) );
     572           0 :     switch( meType )
     573             :     {
     574             :     case solid:
     575           0 :         pTag->addRGBA( maColor );
     576           0 :         break;
     577             :     case linear_gradient:
     578             :     case radial_gradient:
     579           0 :         Impl_addGradient( pTag );
     580           0 :         break;
     581             :     case tiled_bitmap:
     582             :     case clipped_bitmap:
     583           0 :         pTag->addUI16( mnBitmapId );
     584           0 :         pTag->addMatrix( maMatrix );
     585           0 :         break;
     586             :     }
     587           0 : }
     588             : 
     589             : // -----------------------------------------------------------------------------
     590             : 
     591             : struct GradRecord
     592             : {
     593             :     sal_uInt8   mnRatio;
     594             :     Color       maColor;
     595             : 
     596           0 :     GradRecord( sal_uInt8 nRatio, const Color& rColor ) : mnRatio( nRatio ), maColor( rColor ) {}
     597             : };
     598             : 
     599             : // TODO: better emulation of our gradients
     600           0 : void FillStyle::Impl_addGradient( Tag* pTag ) const
     601             : {
     602           0 :     vector< struct GradRecord > aGradientRecords;
     603           0 :     basegfx::B2DHomMatrix m(basegfx::tools::createRotateB2DHomMatrix((maGradient.GetAngle() - 900) * F_PI1800));
     604             : 
     605           0 :     switch( maGradient.GetStyle() )
     606             :     {
     607             :     case GradientStyle_ELLIPTICAL:
     608             :     case GradientStyle_RADIAL:
     609             :         {
     610           0 :             aGradientRecords.push_back( GradRecord( 0x00, maGradient.GetEndColor() ) );
     611           0 :             aGradientRecords.push_back( GradRecord( 0xff, maGradient.GetStartColor() ) );
     612             : 
     613           0 :             double tx = ( maGradient.GetOfsX() * 32768.0 ) / 100.0;
     614           0 :             double ty = ( maGradient.GetOfsY() * 32768.0 ) / 100.0;
     615           0 :             double scalex = (double)maBoundRect.GetWidth() / 32768.0;
     616           0 :             double scaley = (double)maBoundRect.GetHeight() / 32768.0;
     617             : 
     618           0 :             m.scale( 1.2, 1.2 );
     619             : 
     620           0 :             if( scalex > scaley )
     621             :             {
     622           0 :                 double scale_move = scaley / scalex;
     623             : 
     624           0 :                 m.translate( tx, scale_move * ty );
     625             : 
     626             : 
     627           0 :                 m.scale( scalex, scalex );
     628             :             }
     629             :             else
     630             :             {
     631           0 :                 double scale_move = scalex / scaley;
     632             : 
     633           0 :                 m.translate( scale_move * tx, ty );
     634             : 
     635             : 
     636           0 :                 m.scale( scaley, scaley );
     637             :             }
     638             : 
     639             :         }
     640           0 :         break;
     641             :     case GradientStyle_AXIAL:
     642             :         {
     643           0 :             aGradientRecords.push_back( GradRecord( 0x00, maGradient.GetEndColor() ) );
     644           0 :             aGradientRecords.push_back( GradRecord( 0x80, maGradient.GetStartColor() ) );
     645           0 :             aGradientRecords.push_back( GradRecord( 0xff, maGradient.GetEndColor() ) );
     646           0 :             double tx = ( 32768.0 / 2.0 );
     647           0 :             double ty = ( 32768.0 / 2.0 );
     648           0 :             double scalex = (double)maBoundRect.GetWidth() / 32768.0;
     649           0 :             double scaley = (double)maBoundRect.GetHeight() / 32768.0;
     650             : 
     651           0 :             m.translate( tx, ty );
     652           0 :             m.scale( scalex, scaley );
     653             :         }
     654           0 :         break;
     655             :     case GradientStyle_SQUARE:
     656             :     case GradientStyle_RECT:
     657             :     case GradientStyle_LINEAR:
     658             :         {
     659           0 :             aGradientRecords.push_back( GradRecord( 0x00, maGradient.GetStartColor() ) );
     660           0 :             aGradientRecords.push_back( GradRecord( 0xff, maGradient.GetEndColor() ) );
     661           0 :             double scalex = (double)maBoundRect.GetWidth() / 32768.0;
     662           0 :             double scaley = (double)maBoundRect.GetHeight() / 32768.0;
     663             : 
     664           0 :             m.scale( scalex, scaley );
     665             : 
     666           0 :             m.translate( maBoundRect.GetWidth() / 2.0, maBoundRect.GetHeight() / 2.0 );
     667             :         }
     668           0 :         break;
     669           0 :     case  GradientStyle_FORCE_EQUAL_SIZE: break;
     670             :     }
     671             : 
     672           0 :     m.translate( maBoundRect.Left(), maBoundRect.Top() );
     673             : 
     674           0 :     pTag->addMatrix( m );
     675             : 
     676             :     DBG_ASSERT( aGradientRecords.size() < 8, "Illegal FlashGradient!" );
     677             : 
     678           0 :     pTag->addUI8( static_cast<sal_uInt8>( aGradientRecords.size() ) );
     679             : 
     680           0 :     for(std::vector< GradRecord >::iterator i = aGradientRecords.begin(); i != aGradientRecords.end(); ++i)
     681             :     {
     682           0 :         pTag->addUI8( (*i).mnRatio );
     683           0 :         pTag->addRGBA( (*i).maColor );
     684           0 :     }
     685           0 : }
     686             : 
     687             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10