Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/graph.hxx>
31 : : #include <vcl/bmpacc.hxx>
32 : : #include <svtools/fltcall.hxx>
33 : :
34 : : //============================ XPMWriter ==================================
35 : :
36 : : class XPMWriter {
37 : :
38 : : private:
39 : :
40 : : SvStream& m_rOStm; // Die auszugebende XPM-Datei
41 : : sal_uInt16 mpOStmOldModus;
42 : :
43 : : sal_Bool mbStatus;
44 : : sal_Bool mbTrans;
45 : : BitmapReadAccess* mpAcc;
46 : : sal_uLong mnWidth, mnHeight; // Bildausmass in Pixeln
47 : : sal_uInt16 mnColors;
48 : :
49 : : com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
50 : :
51 : : void ImplCallback( sal_uInt16 nPercent );
52 : : sal_Bool ImplWriteHeader();
53 : : void ImplWritePalette();
54 : : void ImplWriteColor( sal_uInt16 );
55 : : void ImplWriteBody();
56 : : void ImplWriteNumber( sal_Int32 );
57 : : void ImplWritePixel( sal_uLong ) const;
58 : :
59 : : public:
60 : : XPMWriter(SvStream& rOStm);
61 : : ~XPMWriter();
62 : :
63 : : sal_Bool WriteXPM( const Graphic& rGraphic, FilterConfigItem* pFilterConfigItem );
64 : : };
65 : :
66 : : //=================== Methoden von XPMWriter ==============================
67 : :
68 : 0 : XPMWriter::XPMWriter(SvStream& rOStm)
69 : : : m_rOStm(rOStm)
70 : : , mbStatus(sal_True)
71 : : , mbTrans(sal_False)
72 : 0 : , mpAcc(NULL)
73 : : {
74 : 0 : }
75 : :
76 : : // ------------------------------------------------------------------------
77 : :
78 : 0 : XPMWriter::~XPMWriter()
79 : : {
80 : 0 : }
81 : :
82 : : // ------------------------------------------------------------------------
83 : :
84 : 0 : void XPMWriter::ImplCallback( sal_uInt16 nPercent )
85 : : {
86 : 0 : if ( xStatusIndicator.is() )
87 : : {
88 : 0 : if ( nPercent <= 100 )
89 : 0 : xStatusIndicator->setValue( nPercent );
90 : : }
91 : 0 : }
92 : :
93 : : // ------------------------------------------------------------------------
94 : :
95 : 0 : sal_Bool XPMWriter::WriteXPM( const Graphic& rGraphic, FilterConfigItem* pFilterConfigItem)
96 : : {
97 : 0 : Bitmap aBmp;
98 : :
99 : 0 : if ( pFilterConfigItem )
100 : : {
101 : 0 : xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
102 : 0 : if ( xStatusIndicator.is() )
103 : : {
104 : 0 : rtl::OUString aMsg;
105 : 0 : xStatusIndicator->start( aMsg, 100 );
106 : : }
107 : : }
108 : :
109 : 0 : BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
110 : 0 : aBmp = aBmpEx.GetBitmap();
111 : :
112 : 0 : if ( rGraphic.IsTransparent() ) // event. transparente Farbe erzeugen
113 : : {
114 : 0 : mbTrans = sal_True;
115 : 0 : if ( aBmp.GetBitCount() >= 8 ) // wenn noetig Bild auf 8 bit konvertieren
116 : 0 : aBmp.Convert( BMP_CONVERSION_8BIT_TRANS );
117 : : else
118 : 0 : aBmp.Convert( BMP_CONVERSION_4BIT_TRANS );
119 : 0 : aBmp.Replace( aBmpEx.GetMask(), BMP_COL_TRANS );
120 : : }
121 : : else
122 : : {
123 : 0 : if ( aBmp.GetBitCount() > 8 ) // wenn noetig Bild auf 8 bit konvertieren
124 : 0 : aBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
125 : : }
126 : 0 : mpAcc = aBmp.AcquireReadAccess();
127 : 0 : if ( mpAcc )
128 : : {
129 : 0 : mnColors = mpAcc->GetPaletteEntryCount();
130 : 0 : mpOStmOldModus = m_rOStm.GetNumberFormatInt();
131 : 0 : m_rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
132 : :
133 : 0 : if ( ImplWriteHeader() )
134 : : {
135 : 0 : ImplWritePalette();
136 : 0 : ImplWriteBody();
137 : 0 : m_rOStm << "\x22XPMENDEXT\x22\x0a};";
138 : : }
139 : 0 : aBmp.ReleaseAccess( mpAcc );
140 : : }
141 : : else
142 : 0 : mbStatus = sal_False;
143 : :
144 : 0 : m_rOStm.SetNumberFormatInt( mpOStmOldModus );
145 : :
146 : 0 : if ( xStatusIndicator.is() )
147 : 0 : xStatusIndicator->end();
148 : :
149 : 0 : return mbStatus;
150 : : }
151 : :
152 : : // ------------------------------------------------------------------------
153 : :
154 : 0 : sal_Bool XPMWriter::ImplWriteHeader()
155 : : {
156 : 0 : mnWidth = mpAcc->Width();
157 : 0 : mnHeight = mpAcc->Height();
158 : 0 : if ( mnWidth && mnHeight && mnColors )
159 : : {
160 : 0 : m_rOStm << "/* XPM */\x0astatic char * image[] = \x0a{\x0a\x22";
161 : 0 : ImplWriteNumber( mnWidth );
162 : 0 : m_rOStm << (sal_uInt8)32;
163 : 0 : ImplWriteNumber( mnHeight );
164 : 0 : m_rOStm << (sal_uInt8)32;
165 : 0 : ImplWriteNumber( mnColors );
166 : 0 : m_rOStm << (sal_uInt8)32;
167 : 0 : ImplWriteNumber( ( mnColors > 26 ) ? 2 : 1 );
168 : 0 : m_rOStm << "\x22,\x0a";
169 : : }
170 : 0 : else mbStatus = sal_False;
171 : 0 : return mbStatus;
172 : : }
173 : :
174 : : // ------------------------------------------------------------------------
175 : :
176 : 0 : void XPMWriter::ImplWritePalette()
177 : : {
178 : 0 : sal_uInt16 nTransIndex = 0xffff;
179 : :
180 : 0 : if ( mbTrans )
181 : 0 : nTransIndex = mpAcc->GetBestMatchingColor( BMP_COL_TRANS );
182 : 0 : for ( sal_uInt16 i = 0; i < mnColors; i++ )
183 : : {
184 : 0 : m_rOStm << "\x22";
185 : 0 : ImplWritePixel( i );
186 : 0 : m_rOStm << (sal_uInt8)32;
187 : 0 : if ( nTransIndex != i )
188 : : {
189 : 0 : ImplWriteColor( i );
190 : 0 : m_rOStm << "\x22,\x0a";
191 : : }
192 : : else
193 : 0 : m_rOStm << "c none\x22,\x0a";
194 : : }
195 : 0 : }
196 : :
197 : : // ------------------------------------------------------------------------
198 : :
199 : 0 : void XPMWriter::ImplWriteBody()
200 : : {
201 : 0 : for ( sal_uLong y = 0; y < mnHeight; y++ )
202 : : {
203 : 0 : ImplCallback( (sal_uInt16)( ( 100 * y ) / mnHeight ) ); // processing output in percent
204 : 0 : m_rOStm << (sal_uInt8)0x22;
205 : 0 : for ( sal_uLong x = 0; x < mnWidth; x++ )
206 : : {
207 : 0 : ImplWritePixel( (sal_uInt8)(mpAcc->GetPixel( y, x ) ) );
208 : : }
209 : 0 : m_rOStm << "\x22,\x0a";
210 : : }
211 : 0 : }
212 : :
213 : : // ------------------------------------------------------------------------
214 : : // eine Dezimalzahl im ASCII format wird in den Stream geschrieben
215 : :
216 : 0 : void XPMWriter::ImplWriteNumber(sal_Int32 nNumber)
217 : : {
218 : 0 : const rtl::OString aNum(rtl::OString::valueOf(nNumber));
219 : 0 : m_rOStm << aNum.getStr();
220 : 0 : }
221 : :
222 : : // ------------------------------------------------------------------------
223 : :
224 : 0 : void XPMWriter::ImplWritePixel( sal_uLong nCol ) const
225 : : {
226 : 0 : if ( mnColors > 26 )
227 : : {
228 : 0 : sal_uInt8 nDiff = (sal_uInt8) ( nCol / 26 );
229 : 0 : m_rOStm << (sal_uInt8)( nDiff + 'A' );
230 : 0 : m_rOStm << (sal_uInt8)( nCol - ( nDiff*26 ) + 'A' );
231 : : }
232 : : else
233 : 0 : m_rOStm << (sal_uInt8)( nCol + 'A' );
234 : 0 : }
235 : :
236 : : // ------------------------------------------------------------------------
237 : : // ein Farbwert wird im Hexadezimalzahlformat in den Stream geschrieben
238 : 0 : void XPMWriter::ImplWriteColor( sal_uInt16 nNumber )
239 : : {
240 : : sal_uLong nTmp;
241 : : sal_uInt8 j;
242 : :
243 : 0 : m_rOStm << "c #"; // # zeigt einen folgenden Hexwert an
244 : 0 : const BitmapColor& rColor = mpAcc->GetPaletteColor( nNumber );
245 : 0 : nTmp = ( rColor.GetRed() << 16 ) | ( rColor.GetGreen() << 8 ) | rColor.GetBlue();
246 : 0 : for ( signed char i = 20; i >= 0 ; i-=4 )
247 : : {
248 : 0 : if ( ( j = (sal_uInt8)( nTmp >> i ) & 0xf ) > 9 )
249 : 0 : j += 'A' - 10;
250 : : else
251 : 0 : j += '0';
252 : 0 : m_rOStm << j;
253 : : }
254 : 0 : }
255 : :
256 : : // ------------------------------------------------------------------------
257 : :
258 : : // ---------------------
259 : : // - exported function -
260 : : // ---------------------
261 : :
262 : : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool __LOADONCALLAPI
263 : 0 : GraphicExport(SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pFilterConfigItem, sal_Bool)
264 : : {
265 : 0 : XPMWriter aXPMWriter(rStream);
266 : :
267 : 0 : return aXPMWriter.WriteXPM( rGraphic, pFilterConfigItem );
268 : : }
269 : :
270 : :
271 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|