| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svtools.hxx" |
| |
| #include <tools/color.hxx> |
| #include <vcl/bmpacc.hxx> |
| #include <vcl/bitmapex.hxx> |
| #include <vcl/alpha.hxx> |
| #include <vcl/pngread.hxx> |
| #include <vcl/pngwrite.hxx> |
| #include "bmpcore.hxx" |
| #include <vcl/dibtools.hxx> |
| #include <vector> |
| #include <algorithm> |
| |
| #undef WRITE_ALPHA_PNG |
| |
| // ------------------------- |
| // - ImplGetSystemFileName - |
| // ------------------------- |
| |
| static String ImplGetSystemFileName( const String& rFileName ) |
| { |
| String aRet( rFileName ); |
| const sal_Unicode aReplace = DirEntry::GetAccessDelimiter( FSYS_STYLE_HOST ).GetChar( 0 ); |
| |
| aRet.SearchAndReplaceAll( '/', aReplace ); |
| aRet.SearchAndReplaceAll( '\\', aReplace ); |
| |
| return aRet; |
| } |
| |
| // -------------- |
| // - BmpCreator - |
| // -------------- |
| |
| BmpCreator::BmpCreator() |
| { |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| BmpCreator::~BmpCreator() |
| { |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| void BmpCreator::Message( const String&, sal_uInt8 ) |
| { |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void BmpCreator::ImplCreate( const ::std::vector< DirEntry >& rInDirs, |
| const DirEntry& rOut, |
| const String& rName, |
| const LangInfo& rLang ) |
| { |
| const sal_uInt32 nOldPos = pSRS->Tell(); |
| const char* pCollectFile = getenv( "BMP_COLLECT_FILE" ); |
| SvFileStream* pCollectStm = pCollectFile ? new SvFileStream( String( pCollectFile, RTL_TEXTENCODING_ASCII_US ), |
| STREAM_WRITE ) : NULL; |
| |
| if( pCollectStm ) |
| pCollectStm->Seek( STREAM_SEEK_TO_END ); |
| |
| if( rInDirs.size() ) |
| { |
| ByteString aLine; |
| String aInfo, aPrefix, aName( rName ), aString; |
| SvFileStream aOutStream; |
| BitmapEx aTotalBmpEx; |
| DirEntry aOutFile( rOut ); |
| ::std::vector< DirEntry > aInFiles( rInDirs ); |
| ::std::vector< String > aNameVector; |
| sal_uInt32 i; |
| |
| for( i = 0; i < aInFiles.size(); i++ ) |
| aInFiles[ i ] += DirEntry( String( RTL_CONSTASCII_USTRINGPARAM( "xxx.xxx" ) ) ); |
| |
| // get prefix for files |
| if( ( aName.Len() >= 3 ) && ( aName.GetChar( 2 ) != '_' ) ) |
| aPrefix = String( aName, 0, 3 ); |
| else |
| aPrefix = String( aName, 0, 2 ); |
| |
| String aNumStr( String::CreateFromAscii( rLang.maLangDir )) ; |
| |
| if( aNumStr.Len() == 1 ) |
| aNumStr.Insert( '0', 0 ); |
| |
| aName = DirEntry( aName ).GetBase(); |
| aName += String( RTL_CONSTASCII_USTRINGPARAM( ".bmp" ) ); |
| |
| // create output file name |
| aOutFile += DirEntry( aName ); |
| |
| // get number of bitmaps |
| while( aLine.Search( '}' ) == STRING_NOTFOUND ) |
| { |
| if( !pSRS->ReadLine( aLine ) ) |
| break; |
| |
| aLine.EraseLeadingChars( ' ' ); |
| aLine.EraseLeadingChars( '\t' ); |
| aLine.EraseAllChars( ';' ); |
| |
| if( aLine.IsNumericAscii() ) |
| { |
| aString = aPrefix; |
| |
| if( atoi( aLine.GetBuffer() ) < 10000 ) |
| aString += String::CreateFromInt32( 0 ); |
| |
| // search for pngs by default |
| String aPngString( aString += String( aLine.GetBuffer(), RTL_TEXTENCODING_UTF8 ) ); |
| aNameVector.push_back( aPngString += String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ) ); |
| } |
| } |
| |
| if( !aNameVector.size() ) |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "WARNING: No imagelist resource found: " ) ).Append( aString ), EXIT_MISSING_RESOURCE ); |
| else |
| { |
| // write info |
| aInfo = String( RTL_CONSTASCII_USTRINGPARAM( "CREATING ImageList for language: " ) ); |
| aInfo += String( ::rtl::OUString::createFromAscii( rLang.maLangDir ) ); |
| aInfo += String( RTL_CONSTASCII_USTRINGPARAM( " [ " ) ); |
| |
| for( i = 0; i < rInDirs.size(); i++ ) |
| ( aInfo += rInDirs[ i ].GetFull() ) += String( RTL_CONSTASCII_USTRINGPARAM( "; " ) ); |
| |
| aInfo += String( RTL_CONSTASCII_USTRINGPARAM( " ]" ) ); |
| Message( aInfo ); |
| |
| // create bit vector to hold flags for valid bitmaps |
| ::std::bit_vector aValidBmpBitVector( aNameVector.size(), false ); |
| BitmapEx aBmpEx; |
| |
| for( sal_uInt32 n = 0; n < aNameVector.size(); n++ ) |
| { |
| aBmpEx.SetEmpty(); |
| |
| for( i = 0; i < aInFiles.size() && aBmpEx.IsEmpty(); i++ ) |
| { |
| DirEntry aInFile( aInFiles[ i ] ); |
| |
| aInFile.SetName( aString = aNameVector[ n ] ); |
| bool bPNG = aInFile.Exists(); |
| |
| if( !bPNG ) |
| { |
| aInFile.SetExtension( String( RTL_CONSTASCII_USTRINGPARAM( "bmp" ) ) ); |
| aString = aInFile.GetName(); |
| } |
| |
| if( aInFile.Exists() ) |
| { |
| const String aFileName( aInFile.GetFull() ); |
| SvFileStream aIStm( aFileName, STREAM_READ ); |
| |
| if( bPNG ) |
| { |
| ::vcl::PNGReader aPNGReader( aIStm ); |
| aBmpEx = aPNGReader.Read(); |
| } |
| else |
| { |
| ReadDIBBitmapEx(aBmpEx, aIStm); |
| } |
| |
| if( pCollectStm && !aBmpEx.IsEmpty() ) |
| { |
| const ByteString aCollectString( aFileName, RTL_TEXTENCODING_ASCII_US ); |
| pCollectStm->WriteLine( aCollectString ); |
| } |
| } |
| } |
| |
| const Size aSize( aBmpEx.GetSizePixel() ); |
| |
| if( aBmpEx.IsEmpty() ) |
| { |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: graphic is missing: " ) ).Append( aString ), EXIT_MISSING_BITMAP ); |
| } |
| else |
| { |
| if( aTotalBmpEx.IsEmpty() ) |
| { |
| // first bitmap determines metrics of total bitmap |
| Size aTotalSize( aOneSize = aSize ); |
| |
| aTotalSize.Width() *= aNameVector.size(); |
| aTotalBmpEx = Bitmap( aTotalSize, aBmpEx.GetBitmap().GetBitCount() ); |
| } |
| |
| if( ( aSize.Width() > aOneSize.Width() ) || ( aSize.Height() > aOneSize.Height() ) ) |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Different dimensions in file: " ) ).Append( aString ), EXIT_DIMENSIONERROR ); |
| else |
| { |
| Point aPoint; |
| const Rectangle aDst( Point( aOneSize.Width() * n, 0L ), aSize ); |
| const Rectangle aSrc( aPoint, aSize ); |
| |
| if( !aTotalBmpEx.IsEmpty() && !aBmpEx.IsEmpty() && !aDst.IsEmpty() && !aSrc.IsEmpty() ) |
| { |
| if( !aTotalBmpEx.IsTransparent() && aBmpEx.IsTransparent() ) |
| { |
| const Bitmap aTmpBmp( aTotalBmpEx.GetBitmap() ); |
| aTotalBmpEx = BitmapEx( aTmpBmp, AlphaMask( aTmpBmp.CreateMask( COL_LIGHTMAGENTA ) ) ); |
| } |
| else if( aTotalBmpEx.IsTransparent() && !aBmpEx.IsTransparent() ) |
| { |
| const Bitmap aTmpBmp( aBmpEx.GetBitmap() ); |
| aBmpEx = BitmapEx( aTmpBmp, AlphaMask( aTmpBmp.CreateMask( COL_LIGHTMAGENTA ) ) ); |
| } |
| |
| aTotalBmpEx.CopyPixel( aDst, aSrc, &aBmpEx ); |
| aValidBmpBitVector[ n ] = true; |
| } |
| } |
| } |
| } |
| |
| if( !aTotalBmpEx.IsEmpty() ) |
| { |
| // do we have invalid bitmaps? |
| if( ::std::find( aValidBmpBitVector.begin(), aValidBmpBitVector.end(), false ) != aValidBmpBitVector.end() ) |
| { |
| Bitmap aTmpBmp( aTotalBmpEx.GetBitmap() ); |
| BitmapWriteAccess* pAcc = aTmpBmp.AcquireWriteAccess(); |
| |
| if( pAcc ) |
| { |
| pAcc->SetLineColor( Color( COL_LIGHTGREEN ) ); |
| |
| for( sal_uInt32 n = 0; n < aValidBmpBitVector.size(); n++ ) |
| { |
| if( !aValidBmpBitVector[ n ] ) |
| { |
| const Rectangle aDst( Point( aOneSize.Width() * n, 0L ), aOneSize ); |
| |
| pAcc->DrawRect( aDst ); |
| pAcc->DrawLine( aDst.TopLeft(), aDst.BottomRight() ); |
| pAcc->DrawLine( aDst.TopRight(), aDst.BottomLeft() ); |
| } |
| } |
| |
| aTmpBmp.ReleaseAccess( pAcc ); |
| |
| if( aTotalBmpEx.IsAlpha() ) |
| aTotalBmpEx = BitmapEx( aTmpBmp, aTotalBmpEx.GetAlpha() ); |
| else if( aTotalBmpEx.IsTransparent() ) |
| aTotalBmpEx = BitmapEx( aTmpBmp, aTotalBmpEx.GetMask() ); |
| else |
| aTotalBmpEx = aTmpBmp; |
| } |
| } |
| |
| // write output file |
| const String aOutFileName( aOutFile.GetFull() ); |
| |
| aOutStream.Open( aOutFileName, STREAM_WRITE | STREAM_TRUNC ); |
| |
| if( !aOutStream.IsOpen() ) |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Could not open output file: " ) ).Append( aOutFileName ), EXIT_IOERROR ); |
| else |
| { |
| if( aOutFileName.Search( String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ) ) != STRING_NOTFOUND ) |
| { |
| ::vcl::PNGWriter aPNGWriter( aTotalBmpEx ); |
| aPNGWriter.Write( aOutStream ); |
| } |
| else |
| { |
| WriteDIBBitmapEx(aTotalBmpEx, aOutStream); |
| } |
| |
| if( aOutStream.GetError() ) |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Could not write to output file: " ) ).Append( aOutFileName ), EXIT_IOERROR ); |
| else |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "Successfully generated ImageList " ) ).Append( aOutFileName ) ); |
| |
| aOutStream.Close(); |
| } |
| } |
| else |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Could not generate " ) ).Append( aOutFile.GetFull() ), EXIT_COMMONERROR ); |
| |
| Message( ' ' ); |
| } |
| } |
| else |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: SOLARSRC environment variable not set!" ) ), EXIT_MISSING_SOLARSRC_ENV ); |
| |
| pSRS->Seek( nOldPos ); |
| delete pCollectStm; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| void BmpCreator::Create( const String& rSRSName, |
| const ::std::vector< String >& rInDirs, |
| const String& rOutName, |
| const LangInfo& rLang ) |
| { |
| DirEntry aFileName( ImplGetSystemFileName( rSRSName ) ), aOutDir( ImplGetSystemFileName( rOutName ) ); |
| ::std::vector< DirEntry > aInDirs; |
| sal_Bool bDone = sal_False; |
| |
| aFileName.ToAbs(); |
| aOutDir.ToAbs(); |
| |
| // create vector of all valid input directories, |
| // including language subdirectories |
| for( sal_uInt32 i = 0; i < rInDirs.size(); i++ ) |
| { |
| DirEntry aInDir( ImplGetSystemFileName( rInDirs[ i ] ) ); |
| |
| aInDir.ToAbs(); |
| |
| if( aInDir.Exists() ) |
| { |
| DirEntry aLangInDir( aInDir ); |
| |
| if( ( aLangInDir += DirEntry( ::rtl::OUString::createFromAscii( rLang.maLangDir ) ) ).Exists() ) |
| aInDirs.push_back( aLangInDir ); |
| |
| aInDirs.push_back( aInDir ); |
| } |
| } |
| |
| pSRS = new SvFileStream ( aFileName.GetFull(), STREAM_STD_READ ); |
| |
| if( pSRS->GetError() ) |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Kein SRS file!" ) ), EXIT_NOSRSFILE ); |
| else |
| { |
| String aText; |
| ByteString aByteText; |
| sal_Bool bLangDep = sal_False; |
| |
| do |
| { |
| do |
| { |
| if (!pSRS->ReadLine(aByteText)) |
| break; |
| } |
| while ( aByteText.Search( "ImageList" ) == STRING_NOTFOUND ); |
| |
| do |
| { |
| if (!pSRS->ReadLine( aByteText ) ) |
| break; |
| } |
| while ( aByteText.Search( "File" ) == STRING_NOTFOUND ); |
| aText = String::CreateFromAscii( aByteText.GetBuffer() ); |
| |
| const String aName( aText.GetToken( 1, '"' ) ); |
| |
| do |
| { |
| if( !bLangDep && |
| aByteText.Search( "File" ) != STRING_NOTFOUND && |
| aByteText.Search( '[' ) != STRING_NOTFOUND && |
| aByteText.Search( ']' ) != STRING_NOTFOUND ) |
| { |
| bLangDep = sal_True; |
| } |
| |
| if (!pSRS->ReadLine(aByteText)) |
| break; |
| } |
| while (aByteText.Search( "IdList" ) == STRING_NOTFOUND ); |
| aText = String::CreateFromAscii( aByteText.GetBuffer() ); |
| |
| // if image list is not language dependent, don't do anything for languages except german |
| if( aText.Len() ) |
| { |
| bDone = sal_True; |
| ImplCreate( aInDirs, aOutDir, aName, rLang ); |
| } |
| /* else if( ( rLang.mnLangNum != 49 ) && !bLangDep ) |
| { |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "INFO: ImageList is not language dependent! Nothing to do for this language." ) ) ); |
| bDone = sal_True; |
| }*/ |
| } |
| while ( aText.Len() ); |
| } |
| |
| if( !bDone ) |
| Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: No ImageList found in SRS file!" ) ), EXIT_NOIMGLIST ); |
| |
| delete pSRS; |
| } |