Update ooo320-m1
[ooovba.git] / svtools / bmpmaker / bmpcore.cxx
blobad960b9e2ae3cc9547ce2d3e010d9b01d3b7710f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bmpcore.cxx,v $
10 * $Revision: 1.19 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #include <tools/color.hxx>
35 #include <vcl/bmpacc.hxx>
36 #include <vcl/bitmapex.hxx>
37 #include <vcl/alpha.hxx>
38 #include <vcl/pngread.hxx>
39 #include <vcl/pngwrite.hxx>
40 #include "bmpcore.hxx"
42 #include <vector>
43 #include <algorithm>
45 #undef WRITE_ALPHA_PNG
47 // -------------------------
48 // - ImplGetSystemFileName -
49 // -------------------------
51 static String ImplGetSystemFileName( const String& rFileName )
53 String aRet( rFileName );
54 const sal_Unicode aReplace = DirEntry::GetAccessDelimiter( FSYS_STYLE_HOST ).GetChar( 0 );
56 aRet.SearchAndReplaceAll( '/', aReplace );
57 aRet.SearchAndReplaceAll( '\\', aReplace );
59 return aRet;
62 // --------------
63 // - BmpCreator -
64 // --------------
66 BmpCreator::BmpCreator()
70 // -----------------------------------------------------------------------------
72 BmpCreator::~BmpCreator()
76 // -----------------------------------------------------------------------------
78 void BmpCreator::Message( const String&, BYTE )
82 // -----------------------------------------------------------------------
84 void BmpCreator::ImplCreate( const ::std::vector< DirEntry >& rInDirs,
85 const DirEntry& rOut,
86 const String& rName,
87 const LangInfo& rLang )
89 const sal_uInt32 nOldPos = pSRS->Tell();
90 const char* pCollectFile = getenv( "BMP_COLLECT_FILE" );
91 SvFileStream* pCollectStm = pCollectFile ? new SvFileStream( String( pCollectFile, RTL_TEXTENCODING_ASCII_US ),
92 STREAM_WRITE ) : NULL;
94 if( pCollectStm )
95 pCollectStm->Seek( STREAM_SEEK_TO_END );
97 if( rInDirs.size() )
99 ByteString aLine;
100 String aInfo, aPrefix, aName( rName ), aString;
101 SvFileStream aOutStream;
102 BitmapEx aTotalBmpEx;
103 DirEntry aOutFile( rOut );
104 ::std::vector< DirEntry > aInFiles( rInDirs );
105 ::std::vector< String > aNameVector;
106 sal_uInt32 i;
108 for( i = 0; i < aInFiles.size(); i++ )
109 aInFiles[ i ] += DirEntry( String( RTL_CONSTASCII_USTRINGPARAM( "xxx.xxx" ) ) );
111 // get prefix for files
112 if( ( aName.Len() >= 3 ) && ( aName.GetChar( 2 ) != '_' ) )
113 aPrefix = String( aName, 0, 3 );
114 else
115 aPrefix = String( aName, 0, 2 );
117 String aNumStr( String::CreateFromAscii( rLang.maLangDir )) ;
119 if( aNumStr.Len() == 1 )
120 aNumStr.Insert( '0', 0 );
122 aName = DirEntry( aName ).GetBase();
123 aName += String( RTL_CONSTASCII_USTRINGPARAM( ".bmp" ) );
125 // create output file name
126 aOutFile += DirEntry( aName );
128 // get number of bitmaps
129 while( aLine.Search( '}' ) == STRING_NOTFOUND )
131 if( !pSRS->ReadLine( aLine ) )
132 break;
134 aLine.EraseLeadingChars( ' ' );
135 aLine.EraseLeadingChars( '\t' );
136 aLine.EraseAllChars( ';' );
138 if( aLine.IsNumericAscii() )
140 aString = aPrefix;
142 if( atoi( aLine.GetBuffer() ) < 10000 )
143 aString += String::CreateFromInt32( 0 );
145 // search for pngs by default
146 String aPngString( aString += String( aLine.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
147 aNameVector.push_back( aPngString += String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ) );
151 if( !aNameVector.size() )
152 Message( String( RTL_CONSTASCII_USTRINGPARAM( "WARNING: No imagelist resource found: " ) ).Append( aString ), EXIT_MISSING_RESOURCE );
153 else
155 // write info
156 aInfo = String( RTL_CONSTASCII_USTRINGPARAM( "CREATING ImageList for language: " ) );
157 aInfo += String( ::rtl::OUString::createFromAscii( rLang.maLangDir ) );
158 aInfo += String( RTL_CONSTASCII_USTRINGPARAM( " [ " ) );
160 for( i = 0; i < rInDirs.size(); i++ )
161 ( aInfo += rInDirs[ i ].GetFull() ) += String( RTL_CONSTASCII_USTRINGPARAM( "; " ) );
163 aInfo += String( RTL_CONSTASCII_USTRINGPARAM( " ]" ) );
164 Message( aInfo );
166 // create bit vector to hold flags for valid bitmaps
167 ::std::bit_vector aValidBmpBitVector( aNameVector.size(), false );
168 BitmapEx aBmpEx;
170 for( sal_uInt32 n = 0; n < aNameVector.size(); n++ )
172 aBmpEx.SetEmpty();
174 for( i = 0; i < aInFiles.size() && aBmpEx.IsEmpty(); i++ )
176 DirEntry aInFile( aInFiles[ i ] );
178 aInFile.SetName( aString = aNameVector[ n ] );
179 bool bPNG = aInFile.Exists();
181 if( !bPNG )
183 aInFile.SetExtension( String( RTL_CONSTASCII_USTRINGPARAM( "bmp" ) ) );
184 aString = aInFile.GetName();
187 if( aInFile.Exists() )
189 const String aFileName( aInFile.GetFull() );
190 SvFileStream aIStm( aFileName, STREAM_READ );
192 if( bPNG )
194 ::vcl::PNGReader aPNGReader( aIStm );
195 aBmpEx = aPNGReader.Read();
197 else
198 aIStm >> aBmpEx;
200 if( pCollectStm && !aBmpEx.IsEmpty() )
202 const ByteString aCollectString( aFileName, RTL_TEXTENCODING_ASCII_US );
203 pCollectStm->WriteLine( aCollectString );
208 const Size aSize( aBmpEx.GetSizePixel() );
210 if( aBmpEx.IsEmpty() )
212 Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: graphic is missing: " ) ).Append( aString ), EXIT_MISSING_BITMAP );
214 else
216 if( aTotalBmpEx.IsEmpty() )
218 // first bitmap determines metrics of total bitmap
219 Size aTotalSize( aOneSize = aSize );
221 aTotalSize.Width() *= aNameVector.size();
222 aTotalBmpEx = Bitmap( aTotalSize, aBmpEx.GetBitmap().GetBitCount() );
225 if( ( aSize.Width() > aOneSize.Width() ) || ( aSize.Height() > aOneSize.Height() ) )
226 Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Different dimensions in file: " ) ).Append( aString ), EXIT_DIMENSIONERROR );
227 else
229 Point aPoint;
230 const Rectangle aDst( Point( aOneSize.Width() * n, 0L ), aSize );
231 const Rectangle aSrc( aPoint, aSize );
233 if( !aTotalBmpEx.IsEmpty() && !aBmpEx.IsEmpty() && !aDst.IsEmpty() && !aSrc.IsEmpty() )
235 if( !aTotalBmpEx.IsTransparent() && aBmpEx.IsTransparent() )
237 const Bitmap aTmpBmp( aTotalBmpEx.GetBitmap() );
238 aTotalBmpEx = BitmapEx( aTmpBmp, AlphaMask( aTmpBmp.CreateMask( COL_LIGHTMAGENTA ) ) );
240 else if( aTotalBmpEx.IsTransparent() && !aBmpEx.IsTransparent() )
242 const Bitmap aTmpBmp( aBmpEx.GetBitmap() );
243 aBmpEx = BitmapEx( aTmpBmp, AlphaMask( aTmpBmp.CreateMask( COL_LIGHTMAGENTA ) ) );
246 aTotalBmpEx.CopyPixel( aDst, aSrc, &aBmpEx );
247 aValidBmpBitVector[ n ] = true;
253 if( !aTotalBmpEx.IsEmpty() )
255 // do we have invalid bitmaps?
256 if( ::std::find( aValidBmpBitVector.begin(), aValidBmpBitVector.end(), false ) != aValidBmpBitVector.end() )
258 Bitmap aTmpBmp( aTotalBmpEx.GetBitmap() );
259 BitmapWriteAccess* pAcc = aTmpBmp.AcquireWriteAccess();
261 if( pAcc )
263 pAcc->SetLineColor( Color( COL_LIGHTGREEN ) );
265 for( sal_uInt32 n = 0; n < aValidBmpBitVector.size(); n++ )
267 if( !aValidBmpBitVector[ n ] )
269 const Rectangle aDst( Point( aOneSize.Width() * n, 0L ), aOneSize );
271 pAcc->DrawRect( aDst );
272 pAcc->DrawLine( aDst.TopLeft(), aDst.BottomRight() );
273 pAcc->DrawLine( aDst.TopRight(), aDst.BottomLeft() );
277 aTmpBmp.ReleaseAccess( pAcc );
279 if( aTotalBmpEx.IsAlpha() )
280 aTotalBmpEx = BitmapEx( aTmpBmp, aTotalBmpEx.GetAlpha() );
281 else if( aTotalBmpEx.IsTransparent() )
282 aTotalBmpEx = BitmapEx( aTmpBmp, aTotalBmpEx.GetMask() );
283 else
284 aTotalBmpEx = aTmpBmp;
288 // write output file
289 const String aOutFileName( aOutFile.GetFull() );
291 aOutStream.Open( aOutFileName, STREAM_WRITE | STREAM_TRUNC );
293 if( !aOutStream.IsOpen() )
294 Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Could not open output file: " ) ).Append( aOutFileName ), EXIT_IOERROR );
295 else
297 if( aOutFileName.Search( String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ) ) != STRING_NOTFOUND )
299 ::vcl::PNGWriter aPNGWriter( aTotalBmpEx );
300 aPNGWriter.Write( aOutStream );
302 else
303 aOutStream << aTotalBmpEx;
305 if( aOutStream.GetError() )
306 Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Could not write to output file: " ) ).Append( aOutFileName ), EXIT_IOERROR );
307 else
308 Message( String( RTL_CONSTASCII_USTRINGPARAM( "Successfully generated ImageList " ) ).Append( aOutFileName ) );
310 aOutStream.Close();
313 else
314 Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Could not generate " ) ).Append( aOutFile.GetFull() ), EXIT_COMMONERROR );
316 Message( ' ' );
319 else
320 Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: SOLARSRC environment variable not set!" ) ), EXIT_MISSING_SOLARSRC_ENV );
322 pSRS->Seek( nOldPos );
323 delete pCollectStm;
326 // -----------------------------------------------------------------------------
328 void BmpCreator::Create( const String& rSRSName,
329 const ::std::vector< String >& rInDirs,
330 const String& rOutName,
331 const LangInfo& rLang )
333 DirEntry aFileName( ImplGetSystemFileName( rSRSName ) ), aOutDir( ImplGetSystemFileName( rOutName ) );
334 ::std::vector< DirEntry > aInDirs;
335 BOOL bDone = FALSE;
337 aFileName.ToAbs();
338 aOutDir.ToAbs();
340 // create vector of all valid input directories,
341 // including language subdirectories
342 for( sal_uInt32 i = 0; i < rInDirs.size(); i++ )
344 DirEntry aInDir( ImplGetSystemFileName( rInDirs[ i ] ) );
346 aInDir.ToAbs();
348 if( aInDir.Exists() )
350 DirEntry aLangInDir( aInDir );
352 if( ( aLangInDir += DirEntry( ::rtl::OUString::createFromAscii( rLang.maLangDir ) ) ).Exists() )
353 aInDirs.push_back( aLangInDir );
355 aInDirs.push_back( aInDir );
359 pSRS = new SvFileStream ( aFileName.GetFull(), STREAM_STD_READ );
361 if( pSRS->GetError() )
362 Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Kein SRS file!" ) ), EXIT_NOSRSFILE );
363 else
365 String aText;
366 ByteString aByteText;
367 BOOL bLangDep = FALSE;
373 if (!pSRS->ReadLine(aByteText))
374 break;
376 while ( aByteText.Search( "ImageList" ) == STRING_NOTFOUND );
380 if (!pSRS->ReadLine( aByteText ) )
381 break;
383 while ( aByteText.Search( "File" ) == STRING_NOTFOUND );
384 aText = String::CreateFromAscii( aByteText.GetBuffer() );
386 const String aName( aText.GetToken( 1, '"' ) );
390 if( !bLangDep &&
391 aByteText.Search( "File" ) != STRING_NOTFOUND &&
392 aByteText.Search( '[' ) != STRING_NOTFOUND &&
393 aByteText.Search( ']' ) != STRING_NOTFOUND )
395 bLangDep = TRUE;
398 if (!pSRS->ReadLine(aByteText))
399 break;
401 while (aByteText.Search( "IdList" ) == STRING_NOTFOUND );
402 aText = String::CreateFromAscii( aByteText.GetBuffer() );
404 // if image list is not language dependent, don't do anything for languages except german
405 if( aText.Len() )
407 bDone = TRUE;
408 ImplCreate( aInDirs, aOutDir, aName, rLang );
410 /* else if( ( rLang.mnLangNum != 49 ) && !bLangDep )
412 Message( String( RTL_CONSTASCII_USTRINGPARAM( "INFO: ImageList is not language dependent! Nothing to do for this language." ) ) );
413 bDone = TRUE;
416 while ( aText.Len() );
419 if( !bDone )
420 Message( String( RTL_CONSTASCII_USTRINGPARAM( "ERROR: No ImageList found in SRS file!" ) ), EXIT_NOIMGLIST );
422 delete pSRS;