xref: /trunk/main/editeng/source/rtf/rtfgrf.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_editeng.hxx"
30 
31 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
32 #include <osl/endian.h>
33 #include <tools/cachestr.hxx>
34 #include <vcl/graph.hxx>
35 #include <vcl/svapp.hxx>
36 #include <svtools/rtfkeywd.hxx>
37 #include <svtools/rtftoken.h>
38 #include <svtools/filter.hxx>
39 
40 #include <editeng/svxrtf.hxx>
41 
42 using namespace ::rtl;
43 
44 #ifndef DBG_UTIL
45 #undef DEBUG_JP
46 #endif
47 
48 #ifdef DEBUG_JP
49 
50 #include <tools/fsys.hxx>
51 
52 class GrfWindow : public WorkWindow
53 {
54     Graphic aGrf;
55 public:
56     GrfWindow( const Graphic& rGrf );
57     virtual void    Paint( const Rectangle& rRect );
58 };
59 
60 GrfWindow::GrfWindow( const Graphic& rGrf )
61     : WorkWindow( NULL ),
62     aGrf( rGrf )
63 {
64     SetPosSizePixel( Point( 100, 0 ), Size( 300, 300 ));
65     Show();
66     Invalidate();
67     Update();
68 }
69 
70 void GrfWindow::Paint( const Rectangle& )
71 {
72     aGrf.Draw( this, Point(0,0), GetSizePixel() );
73 }
74 #endif
75 
76 static sal_uInt8 __FAR_DATA aPal1[ 2 * 4 ] = {
77         0x00, 0x00, 0x00, 0x00,             // Schwarz
78         0xFF, 0xFF, 0xFF, 0x00              // Weiss
79 };
80 
81 static sal_uInt8 __FAR_DATA aPal4[ 16 * 4 ] = {
82         0x00, 0x00, 0x00, 0x00,
83         0x80, 0x00, 0x00, 0x00,
84         0x00, 0x80, 0x00, 0x00,
85         0x80, 0x80, 0x00, 0x00,
86         0x00, 0x00, 0x80, 0x00,
87         0x80, 0x00, 0x80, 0x00,
88         0x00, 0x80, 0x80, 0x00,
89         0x80, 0x80, 0x80, 0x00,
90         0xC0, 0xC0, 0xC0, 0x00,
91         0xFF, 0x00, 0x00, 0x00,
92         0x00, 0xFF, 0x00, 0x00,
93         0xFF, 0xFF, 0x00, 0x00,
94         0x00, 0x00, 0xFF, 0x00,
95         0xFF, 0x00, 0xFF, 0x00,
96         0x00, 0xFF, 0xFF, 0x00,
97         0xFF, 0xFF, 0xFF, 0x00
98 };
99 
100 static sal_uInt8 __FAR_DATA aPal8[ 256 * 4 ] =
101 {
102 0x00, 0x00, 0x00, 0x00,   0x80, 0x00, 0x00, 0x00,   0x00, 0x92, 0x00, 0x00,
103 0x80, 0x92, 0x00, 0x00,   0x00, 0x00, 0xAA, 0x00,   0x80, 0x00, 0xAA, 0x00,
104 0x00, 0x92, 0xAA, 0x00,   0xC1, 0xC1, 0xC1, 0x00,   0xC9, 0xC9, 0xC9, 0x00,
105 0xAA, 0xDB, 0xFF, 0x00,   0x00, 0x49, 0xAA, 0x00,   0x00, 0x49, 0xFF, 0x00,
106 0x00, 0x6D, 0x00, 0x00,   0x00, 0x6D, 0x55, 0x00,   0x00, 0x6D, 0xAA, 0x00,
107 0x00, 0x6D, 0xFF, 0x00,   0x00, 0x24, 0x00, 0x00,   0x00, 0x92, 0x55, 0x00,
108 0x00, 0x24, 0xAA, 0x00,   0x00, 0x92, 0xFF, 0x00,   0x00, 0xB6, 0x00, 0x00,
109 0x00, 0xB6, 0x55, 0x00,   0x00, 0xB6, 0xAA, 0x00,   0x00, 0xB6, 0xFF, 0x00,
110 0x00, 0xDB, 0x00, 0x00,   0x00, 0xDB, 0x55, 0x00,   0x00, 0xDB, 0xAA, 0x00,
111 0x00, 0xDB, 0xFF, 0x00,   0xFF, 0xDB, 0xAA, 0x00,   0x00, 0xFF, 0x55, 0x00,
112 0x00, 0xFF, 0xAA, 0x00,   0xFF, 0xFF, 0xAA, 0x00,   0x2B, 0x00, 0x00, 0x00,
113 0x2B, 0x00, 0x55, 0x00,   0x2B, 0x00, 0xAA, 0x00,   0x2B, 0x00, 0xFF, 0x00,
114 0x2B, 0x24, 0x00, 0x00,   0x2B, 0x24, 0x55, 0x00,   0x2B, 0x24, 0xAA, 0x00,
115 0x2B, 0x24, 0xFF, 0x00,   0x2B, 0x49, 0x00, 0x00,   0x2B, 0x49, 0x55, 0x00,
116 0x2B, 0x49, 0xAA, 0x00,   0x2B, 0x49, 0xFF, 0x00,   0x2B, 0x6D, 0x00, 0x00,
117 0x2B, 0x6D, 0x55, 0x00,   0x2B, 0x6D, 0xAA, 0x00,   0x2B, 0x6D, 0xFF, 0x00,
118 0x2B, 0x92, 0x00, 0x00,   0x2B, 0x92, 0x55, 0x00,   0x2B, 0x92, 0xAA, 0x00,
119 0x2B, 0x92, 0xFF, 0x00,   0x2B, 0xB6, 0x00, 0x00,   0x2B, 0xB6, 0x55, 0x00,
120 0x2B, 0xB6, 0xAA, 0x00,   0x2B, 0xB6, 0xFF, 0x00,   0x2B, 0xDB, 0x00, 0x00,
121 0x2B, 0xDB, 0x55, 0x00,   0x2B, 0xDB, 0xAA, 0x00,   0x2B, 0xDB, 0xFF, 0x00,
122 0x2B, 0xFF, 0x00, 0x00,   0x2B, 0xFF, 0x55, 0x00,   0x2B, 0xFF, 0xAA, 0x00,
123 0x2B, 0xFF, 0xFF, 0x00,   0x55, 0x00, 0x00, 0x00,   0x55, 0x00, 0x55, 0x00,
124 0x55, 0x00, 0xAA, 0x00,   0x55, 0x00, 0xFF, 0x00,   0x55, 0x24, 0x00, 0x00,
125 0x55, 0x24, 0x55, 0x00,   0x55, 0x24, 0xAA, 0x00,   0x55, 0x24, 0xFF, 0x00,
126 0x55, 0x49, 0x00, 0x00,   0x55, 0x49, 0x55, 0x00,   0x55, 0x49, 0xAA, 0x00,
127 0x55, 0x49, 0xFF, 0x00,   0x55, 0x6D, 0x00, 0x00,   0x55, 0x6D, 0x55, 0x00,
128 0x55, 0x6D, 0xAA, 0x00,   0x55, 0x6D, 0xFF, 0x00,   0x55, 0x92, 0x00, 0x00,
129 0x55, 0x92, 0x55, 0x00,   0x55, 0x92, 0xAA, 0x00,   0x55, 0x92, 0xFF, 0x00,
130 0x55, 0xB6, 0x00, 0x00,   0x55, 0xB6, 0x55, 0x00,   0x55, 0xB6, 0xAA, 0x00,
131 0x55, 0xB6, 0xFF, 0x00,   0x55, 0xDB, 0x00, 0x00,   0x55, 0xDB, 0x55, 0x00,
132 0x55, 0xDB, 0xAA, 0x00,   0x55, 0xDB, 0xFF, 0x00,   0x55, 0xFF, 0x00, 0x00,
133 0x55, 0xFF, 0x55, 0x00,   0x55, 0xFF, 0xAA, 0x00,   0x55, 0xFF, 0xFF, 0x00,
134 0x00, 0x00, 0x55, 0x00,   0x80, 0x00, 0x55, 0x00,   0x00, 0x24, 0x55, 0x00,
135 0x80, 0x00, 0xFF, 0x00,   0x80, 0x24, 0x00, 0x00,   0x80, 0x24, 0x55, 0x00,
136 0x80, 0x24, 0xAA, 0x00,   0x80, 0x24, 0xFF, 0x00,   0x80, 0x49, 0x00, 0x00,
137 0x80, 0x49, 0x55, 0x00,   0x80, 0x49, 0xAA, 0x00,   0x80, 0x49, 0xFF, 0x00,
138 0x80, 0x6D, 0x00, 0x00,   0x80, 0x6D, 0x55, 0x00,   0x80, 0x6D, 0xAA, 0x00,
139 0x80, 0x6D, 0xFF, 0x00,   0x08, 0x08, 0x08, 0x00,   0x0F, 0x0F, 0x0F, 0x00,
140 0x17, 0x17, 0x17, 0x00,   0x1F, 0x1F, 0x1F, 0x00,   0x27, 0x27, 0x27, 0x00,
141 0x2E, 0x2E, 0x2E, 0x00,   0x36, 0x36, 0x36, 0x00,   0x3E, 0x3E, 0x3E, 0x00,
142 0x46, 0x46, 0x46, 0x00,   0x4D, 0x4D, 0x4D, 0x00,   0x55, 0x55, 0x55, 0x00,
143 0x5D, 0x5D, 0x5D, 0x00,   0x64, 0x64, 0x64, 0x00,   0x6C, 0x6C, 0x6C, 0x00,
144 0x74, 0x74, 0x74, 0x00,   0x7C, 0x7C, 0x7C, 0x00,   0xFF, 0xDB, 0x00, 0x00,
145 0x8B, 0x8B, 0x8B, 0x00,   0x93, 0x93, 0x93, 0x00,   0x9B, 0x9B, 0x9B, 0x00,
146 0xFF, 0xB6, 0xFF, 0x00,   0xAA, 0xAA, 0xAA, 0x00,   0xB2, 0xB2, 0xB2, 0x00,
147 0xB9, 0xB9, 0xB9, 0x00,   0x00, 0x24, 0xFF, 0x00,   0x00, 0x49, 0x00, 0x00,
148 0xD1, 0xD1, 0xD1, 0x00,   0xD8, 0xD8, 0xD8, 0x00,   0xE0, 0xE0, 0xE0, 0x00,
149 0xE8, 0xE8, 0xE8, 0x00,   0xF0, 0xF0, 0xF0, 0x00,   0xFF, 0xB6, 0xAA, 0x00,
150 0xFF, 0xDB, 0xFF, 0x00,   0x80, 0x92, 0x55, 0x00,   0x80, 0x92, 0xAA, 0x00,
151 0x80, 0x92, 0xFF, 0x00,   0x80, 0xB6, 0x00, 0x00,   0x80, 0xB6, 0x55, 0x00,
152 0x80, 0xB6, 0xAA, 0x00,   0x80, 0xB6, 0xFF, 0x00,   0x80, 0xDB, 0x00, 0x00,
153 0x80, 0xDB, 0x55, 0x00,   0x80, 0xDB, 0xAA, 0x00,   0x80, 0xDB, 0xFF, 0x00,
154 0x80, 0xFF, 0x00, 0x00,   0x80, 0xFF, 0x55, 0x00,   0x80, 0xFF, 0xAA, 0x00,
155 0x80, 0xFF, 0xFF, 0x00,   0xAA, 0x00, 0x00, 0x00,   0xAA, 0x00, 0x55, 0x00,
156 0xAA, 0x00, 0xAA, 0x00,   0xAA, 0x00, 0xFF, 0x00,   0xAA, 0x24, 0x00, 0x00,
157 0xAA, 0x24, 0x55, 0x00,   0xAA, 0x24, 0xAA, 0x00,   0xAA, 0x24, 0xFF, 0x00,
158 0xAA, 0x49, 0x00, 0x00,   0xAA, 0x49, 0x55, 0x00,   0xAA, 0x49, 0xAA, 0x00,
159 0xAA, 0x49, 0xFF, 0x00,   0xAA, 0x6D, 0x00, 0x00,   0xAA, 0x6D, 0x55, 0x00,
160 0xAA, 0x6D, 0xAA, 0x00,   0xAA, 0x6D, 0xFF, 0x00,   0xAA, 0x92, 0x00, 0x00,
161 0xAA, 0x92, 0x55, 0x00,   0xAA, 0x92, 0xAA, 0x00,   0xAA, 0x92, 0xFF, 0x00,
162 0xAA, 0xB6, 0x00, 0x00,   0xAA, 0xB6, 0x55, 0x00,   0xAA, 0xB6, 0xAA, 0x00,
163 0xAA, 0xB6, 0xFF, 0x00,   0xAA, 0xDB, 0x00, 0x00,   0xAA, 0xDB, 0x55, 0x00,
164 0xAA, 0xDB, 0xAA, 0x00,   0x00, 0x49, 0x55, 0x00,   0xAA, 0xFF, 0x00, 0x00,
165 0xAA, 0xFF, 0x55, 0x00,   0xAA, 0xFF, 0xAA, 0x00,   0xAA, 0xFF, 0xFF, 0x00,
166 0xD5, 0x00, 0x00, 0x00,   0xD5, 0x00, 0x55, 0x00,   0xD5, 0x00, 0xAA, 0x00,
167 0xD5, 0x00, 0xFF, 0x00,   0xD5, 0x24, 0x00, 0x00,   0xD5, 0x24, 0x55, 0x00,
168 0xD5, 0x24, 0xAA, 0x00,   0xD5, 0x24, 0xFF, 0x00,   0xD5, 0x49, 0x00, 0x00,
169 0xD5, 0x49, 0x55, 0x00,   0xD5, 0x49, 0xAA, 0x00,   0xD5, 0x49, 0xFF, 0x00,
170 0xD5, 0x6D, 0x00, 0x00,   0xD5, 0x6D, 0x55, 0x00,   0xD5, 0x6D, 0xAA, 0x00,
171 0xD5, 0x6D, 0xFF, 0x00,   0xD5, 0x92, 0x00, 0x00,   0xD5, 0x92, 0x55, 0x00,
172 0xD5, 0x92, 0xAA, 0x00,   0xD5, 0x92, 0xFF, 0x00,   0xD5, 0xB6, 0x00, 0x00,
173 0xD5, 0xB6, 0x55, 0x00,   0xD5, 0xB6, 0xAA, 0x00,   0xD5, 0xB6, 0xFF, 0x00,
174 0xD5, 0xDB, 0x00, 0x00,   0xD5, 0xDB, 0x55, 0x00,   0xD5, 0xDB, 0xAA, 0x00,
175 0xD5, 0xDB, 0xFF, 0x00,   0xD5, 0xFF, 0x00, 0x00,   0xD5, 0xFF, 0x55, 0x00,
176 0xD5, 0xFF, 0xAA, 0x00,   0xD5, 0xFF, 0xFF, 0x00,   0xFF, 0xDB, 0x55, 0x00,
177 0xFF, 0x00, 0x55, 0x00,   0xFF, 0x00, 0xAA, 0x00,   0xFF, 0xFF, 0x55, 0x00,
178 0xFF, 0x24, 0x00, 0x00,   0xFF, 0x24, 0x55, 0x00,   0xFF, 0x24, 0xAA, 0x00,
179 0xFF, 0x24, 0xFF, 0x00,   0xFF, 0x49, 0x00, 0x00,   0xFF, 0x49, 0x55, 0x00,
180 0xFF, 0x49, 0xAA, 0x00,   0xFF, 0x49, 0xFF, 0x00,   0xFF, 0x6D, 0x00, 0x00,
181 0xFF, 0x6D, 0x55, 0x00,   0xFF, 0x6D, 0xAA, 0x00,   0xFF, 0x6D, 0xFF, 0x00,
182 0xFF, 0x92, 0x00, 0x00,   0xFF, 0x92, 0x55, 0x00,   0xFF, 0x92, 0xAA, 0x00,
183 0xFF, 0x92, 0xFF, 0x00,   0xFF, 0xB6, 0x00, 0x00,   0xFF, 0xB6, 0x55, 0x00,
184 0xF7, 0xF7, 0xF7, 0x00,   0xA2, 0xA2, 0xA2, 0x00,   0x83, 0x83, 0x83, 0x00,
185 0xFF, 0x00, 0x00, 0x00,   0x00, 0xFF, 0x00, 0x00,   0xFF, 0xFF, 0x00, 0x00,
186 0x00, 0x00, 0xFF, 0x00,   0xFF, 0x00, 0xFF, 0x00,   0x00, 0xFF, 0xFF, 0x00,
187 0xFF, 0xFF, 0xFF, 0x00
188 };
189 
190 
191 /*  */
192 
193 
194 inline long SwapLong( long n )
195 {
196 #ifndef OSL_LITENDIAN
197     return SWAPLONG( n );
198 #else
199     return n;
200 #endif
201 }
202 
203 inline short SwapShort( short n )
204 {
205 #ifndef OSL_LITENDIAN
206     return SWAPSHORT( n );
207 #else
208     return n;
209 #endif
210 }
211 
212 
213 static void WriteBMPHeader( SvStream& rStream,
214                             const SvxRTFPictureType& rPicType )
215 {
216     sal_uInt32 n4Width = rPicType.nWidth;
217     sal_uInt32 n4Height = rPicType.nHeight;
218     sal_uInt16 n4ColBits = rPicType.nBitsPerPixel;
219 
220     sal_uInt16 nColors = (1 << n4ColBits);  // Anzahl der Farben ( 1, 16, 256 )
221     sal_uInt16 nWdtOut = rPicType.nWidthBytes;
222     if( !nWdtOut )
223         nWdtOut = (sal_uInt16)((( n4Width * n4ColBits + 31 ) / 32 ) * 4 );
224 
225     long nOffset = 14 + 40;     // BMP_FILE_HD_SIZ + sizeof(*pBmpInfo);
226     if( 256 >= nColors )
227         nOffset += nColors * 4;
228     long nSize = nOffset + nWdtOut * n4Height;
229     rStream << "BM"                     // = "BM"
230             << SwapLong(nSize)          // Filesize in Bytes
231             << SwapShort(0)             // Reserviert
232             << SwapShort(0)             // Reserviert
233             << SwapLong(nOffset);       // Offset?
234 
235     rStream << SwapLong(40)             // sizeof( BmpInfo )
236             << SwapLong(n4Width)
237             << SwapLong(n4Height)
238             << (sal_uInt16)1
239             << n4ColBits
240             << SwapLong(0)
241             << SwapLong(0)
242             << SwapLong( rPicType.nGoalWidth
243                         ? rPicType.nGoalWidth * 1000L / 254L
244                         : 0 )         // DPI in Pixel per Meter
245             << SwapLong( rPicType.nGoalHeight
246                         ? rPicType.nGoalHeight * 1000L / 254L      // dito
247                         : 0 )
248             << SwapLong(0)
249             << SwapLong(0);
250 
251 
252     switch( rPicType.nBitsPerPixel )
253     {
254     case 1:     rStream.Write( aPal1, sizeof( aPal1 )); break;
255     case 4:     rStream.Write( aPal4, sizeof( aPal4 )); break;
256     case 8:     rStream.Write( aPal8, sizeof( aPal8 )); break;
257     }
258 }
259 
260 /*  */
261 
262         // wandel die ASCII-HexCodes in binaere Zeichen um. Werden
263         // ungueltige Daten gefunden (Zeichen ausser 0-9|a-f|A-F, so
264         // wird USHRT_MAX returnt, ansonsten die Anzahl der umgewandelten Ze.
265 xub_StrLen SvxRTFParser::HexToBin( String& rToken )
266 {
267     // dann mache aus den Hex-Werten mal "Binare Daten"
268     // (missbrauche den String als temp Buffer)
269     if( rToken.Len() & 1 )      // ungerade Anzahl, mit 0 auffuellen
270         rToken += '0';
271 
272     xub_StrLen n, nLen;
273     sal_Unicode nVal;
274     sal_Bool bValidData = sal_True;
275     const sal_Unicode* pStr = rToken.GetBufferAccess();
276     sal_Char* pData = (sal_Char*)pStr;
277     for( n = 0, nLen = rToken.Len(); n < nLen; ++n, ++pStr )
278     {
279         if( ((nVal = *pStr) >= '0') && ( nVal <= '9') )
280             nVal -= '0';
281         else if( (nVal >= 'A') && (nVal <= 'F') )
282             nVal -= 'A' - 10;
283         else if( (nVal >= 'a') && (nVal <= 'f') )
284             nVal -= 'a' - 10;
285         else
286         {
287             DBG_ASSERT( !this, "ungueltiger Hex-Wert" );
288             bValidData = sal_False;
289             break;
290         }
291 
292         if( n & 1 )
293             *(pData++) |= nVal & 0x0f;
294         else
295             *(pData) = sal::static_int_cast< char >( ( nVal << 4 ) & 0xf0 );
296     }
297     // the len div 2, because 2 character are one byte
298     return bValidData ? nLen / 2  : STRING_NOTFOUND;
299 }
300 
301 sal_Bool SvxRTFParser::ReadBmpData( Graphic& rGrf, SvxRTFPictureType& rPicType )
302 {
303     // die alten Daten loeschen
304     rGrf.Clear();
305 //  sal_uInt32 nBmpSize = 0;
306 
307     rtl_TextEncoding eOldEnc = GetSrcEncoding();
308     SetSrcEncoding( RTL_TEXTENCODING_MS_1252 );
309 
310     const sal_Char* pFilterNm = 0;
311     SvCacheStream* pTmpFile = 0;
312 
313     int nToken = 0;
314     bool bValidBmp = true, bFirstTextToken = true;
315     int _nOpenBrakets = 1,      // die erste wurde schon vorher erkannt !!
316         nValidDataBraket = 1;
317 
318     if( RTF_SHPPICT == GetStackPtr(0)->nTokenId )
319         ++nValidDataBraket;
320     OUString sShapePropertyName, sShapePropertyValue;
321     int nShapePropertyBracket = -1;
322     while( _nOpenBrakets && IsParserWorking() && bValidBmp )
323     {
324         nToken = GetNextToken();
325         sal_uInt16 nVal = sal_uInt16( nTokenValue );
326         switch( nToken )
327         {
328         case '}':
329             --_nOpenBrakets;
330             if( nShapePropertyBracket > 0 && nShapePropertyBracket > _nOpenBrakets )
331             {
332                 nShapePropertyBracket = -1;
333                 if( sShapePropertyName.getLength() )
334                 {
335                     rPicType.aPropertyPairs.push_back( ::std::pair< OUString, OUString >( sShapePropertyName, sShapePropertyValue ) );
336                     sShapePropertyName = sShapePropertyValue = ::rtl::OUString();
337                 }
338             }
339         break;
340         case '{':
341             {
342                 if( RTF_IGNOREFLAG != GetNextToken() )
343                     nToken = SkipToken( -1 );
344                 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
345                     nToken = SkipToken( -2 );
346                 else
347                 {
348                     // gleich herausfiltern
349                     ReadUnknownData();
350                     nToken = GetNextToken();
351                     if( '}' != nToken )
352                         eState = SVPAR_ERROR;
353                     break;
354                 }
355                 ++_nOpenBrakets;
356             }
357             break;
358 
359         case RTF_MACPICT:
360             {
361                 rPicType.eStyle = SvxRTFPictureType::MAC_QUICKDRAW;
362                 // Mac-Pict bekommt einen leeren Header voran
363                 pTmpFile = new SvCacheStream;
364                 ByteString aStr;
365                 aStr.Fill( 512, '\0' );
366                 pTmpFile->Write( aStr.GetBuffer(), aStr.Len() );
367                 pFilterNm = "PCT";
368             }
369             break;
370 
371         case RTF_EMFBLIP:
372         case RTF_WMETAFILE:
373         case RTF_PNGBLIP:
374         case RTF_JPEGBLIP:
375         case RTF_WBITMAP:
376         case RTF_OSMETAFILE:
377         case RTF_DIBITMAP:
378             {
379                 switch( nToken )
380                 {
381                 case RTF_EMFBLIP:
382                     rPicType.eStyle = SvxRTFPictureType::ENHANCED_MF;
383                     pFilterNm = "EMF";
384                     break;
385                 case RTF_WMETAFILE:
386                     rPicType.eStyle = SvxRTFPictureType::WIN_METAFILE;
387                     pFilterNm = "WMF";
388                     break;
389                 case RTF_PNGBLIP:
390                     rPicType.eStyle = SvxRTFPictureType::RTF_PNG;
391                     pFilterNm = "PNG";
392                     break;
393                 case RTF_JPEGBLIP:
394                     rPicType.eStyle = SvxRTFPictureType::RTF_JPG;
395                     pFilterNm = "JPG";
396                     break;
397 
398                 case RTF_WBITMAP:
399                     rPicType.eStyle = SvxRTFPictureType::RTF_BITMAP;
400                     break;
401                 case RTF_OSMETAFILE:
402                     rPicType.eStyle = SvxRTFPictureType::OS2_METAFILE;
403                     break;
404                 case RTF_DIBITMAP:
405                     rPicType.eStyle = SvxRTFPictureType::RTF_DI_BMP;
406                     break;
407                 }
408 
409                 rPicType.nType = nVal;
410                 pTmpFile = new SvCacheStream;
411             }
412             break;
413 
414         case RTF_PICW:              rPicType.nWidth = nVal; break;
415         case RTF_PICH:              rPicType.nHeight = nVal; break;
416         case RTF_WBMBITSPIXEL:      rPicType.nBitsPerPixel = nVal; break;
417         case RTF_WBMPLANES:         rPicType.nPlanes = nVal; break;
418         case RTF_WBMWIDTHBYTES:     rPicType.nWidthBytes = nVal; break;
419         case RTF_PICWGOAL:          rPicType.nGoalWidth = nVal; break;
420         case RTF_PICHGOAL:          rPicType.nGoalHeight = nVal; break;
421         case RTF_BIN:
422             rPicType.nMode = SvxRTFPictureType::BINARY_MODE;
423             rPicType.uPicLen = nTokenValue;
424             if (rPicType.uPicLen)
425             {
426                 sal_uInt32 nPos = rStrm.Tell();
427                 nPos = nPos;
428                 rStrm.SeekRel(-1);
429                 sal_uInt8 aData[4096];
430                 sal_uInt32 nSize = sizeof(aData);
431 
432                 while (rPicType.uPicLen > 0)
433                 {
434                     if (rPicType.uPicLen < nSize)
435                         nSize = rPicType.uPicLen;
436 
437                     rStrm.Read(aData, nSize);
438                     pTmpFile->Write(aData, nSize);
439                     rPicType.uPicLen -= nSize;
440                 }
441                 nNextCh = GetNextChar();
442                 bValidBmp = !pTmpFile->GetError();
443                 nPos = rStrm.Tell();
444                 nPos = nPos;
445             }
446             break;
447         case RTF_PICSCALEX:         rPicType.nScalX = nVal; break;
448         case RTF_PICSCALEY:         rPicType.nScalY = nVal; break;
449         case RTF_PICSCALED:         break;
450 
451         case RTF_PICCROPT:          rPicType.nCropT = (short)nTokenValue; break;
452         case RTF_PICCROPB:          rPicType.nCropB = (short)nTokenValue; break;
453         case RTF_PICCROPL:          rPicType.nCropL = (short)nTokenValue; break;
454         case RTF_PICCROPR:          rPicType.nCropR = (short)nTokenValue; break;
455         case RTF_SP:
456             //read pairs of {\sn Name}{\sv Value}
457             nShapePropertyBracket = _nOpenBrakets;
458         break;
459         case RTF_SN:
460             nToken = GetNextToken();
461             if( nToken != '}' )
462                 sShapePropertyName = aToken;
463             else
464                 nToken = SkipToken( -1 );
465         break;
466         case RTF_SV:
467             nToken = GetNextToken();
468             if( nToken != '}' )
469                 sShapePropertyValue = aToken;
470             else
471                 nToken = SkipToken( -1 );
472         break;
473         case RTF_TEXTTOKEN:
474             // JP 26.06.98: Bug #51719# - nur TextToken auf 1. Ebene
475             //              auswerten. Alle anderen sind irgendwelche
476             //              nicht auszuwertende Daten
477             if( nValidDataBraket != _nOpenBrakets )
478                 break;
479 
480             if( bFirstTextToken )
481             {
482                 switch( rPicType.eStyle )
483                 {
484                 case SvxRTFPictureType::RTF_BITMAP:
485                     // erstmal die Header und Info-Struktur schreiben
486                     if( pTmpFile )
487                         ::WriteBMPHeader( *pTmpFile, rPicType );
488                     break;
489                 default:
490                     break;
491                 }
492                 bFirstTextToken = sal_False;
493             }
494 
495             if( pTmpFile && SvxRTFPictureType::HEX_MODE == rPicType.nMode )
496             {
497                 xub_StrLen nTokenLen = HexToBin( aToken );
498                 if( STRING_NOTFOUND == nTokenLen )
499                     bValidBmp = sal_False;
500                 else
501                 {
502                     pTmpFile->Write( (sal_Char*)aToken.GetBuffer(),
503                                         nTokenLen );
504                     bValidBmp = 0 == pTmpFile->GetError();
505                 }
506             }
507             break;
508         }
509     }
510 
511     if (pTmpFile)
512     {
513         //#i20775#
514         if (pTmpFile->Tell() == 0)
515             bValidBmp = false;
516 
517         if( bValidBmp )
518         {
519             GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
520             sal_uInt16 nImportFilter = GRFILTER_FORMAT_DONTKNOW;
521 
522             if( pFilterNm )
523             {
524                 String sTmp;
525                 for( sal_uInt16 n = pGF->GetImportFormatCount(); n; )
526                 {
527                     sTmp = pGF->GetImportFormatShortName( --n );
528                     if( sTmp.EqualsAscii( pFilterNm ))
529                     {
530                         nImportFilter = n;
531                         break;
532                     }
533                 }
534             }
535 
536             String sTmpStr;
537             pTmpFile->Seek( STREAM_SEEK_TO_BEGIN );
538             bValidBmp = 0 == pGF->ImportGraphic( rGrf, sTmpStr, *pTmpFile,
539                                                 nImportFilter );
540         }
541         delete pTmpFile;
542     }
543 
544     if( !bValidBmp )
545     {
546         rGrf.Clear();
547         //TODO  If nToken were not initialized to 0 above, it would potentially
548         // be used uninitialized here (if IsParserWorking() is false at the
549         // start of the while loop above):
550         if( '}' != nToken )
551             SkipGroup();
552     }
553     else
554     {
555         switch( rPicType.eStyle )
556         {
557 //??        ENHANCED_MF,        // in den Pict.Daten steht ein Enhanced-Metafile
558         case SvxRTFPictureType::RTF_PNG:
559         case SvxRTFPictureType::RTF_JPG:
560             {
561                 const MapMode aMap( MAP_100TH_MM );
562                 Size aSize( rGrf.GetPrefSize() );
563                 if( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
564                     aSize = Application::GetDefaultDevice()->PixelToLogic(
565                                         aSize, aMap );
566                 else
567                     aSize = OutputDevice::LogicToLogic( aSize,
568                                         rGrf.GetPrefMapMode(), aMap );
569                 rPicType.nWidth = sal::static_int_cast< sal_uInt16 >(aSize.Width());
570                 rPicType.nHeight = sal::static_int_cast< sal_uInt16 >(
571                     aSize.Height());
572             }
573             break;
574         default:
575             break;
576         }
577 
578 #ifdef DEBUG_JP
579         new GrfWindow( rGrf );
580 #endif
581     }
582     SetSrcEncoding( eOldEnc );
583 
584     SkipToken( -1 );        // die schliesende Klammer wird "oben" ausgewertet
585     return bValidBmp;
586 }
587 
588 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
589