1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef _SWF_WRITER_HXX_
25 #define _SWF_WRITER_HXX_
26
27 #include <com/sun/star/uno/Sequence.hxx>
28 #include <com/sun/star/io/XOutputStream.hpp>
29 #include <com/sun/star/i18n/XBreakIterator.hpp>
30 #include <vcl/font.hxx>
31 #include <vcl/gradient.hxx>
32 #include <unotools/tempfile.hxx>
33 #include <tools/color.hxx>
34 #include <tools/poly.hxx>
35 #include <tools/gen.hxx>
36 #include <tools/stream.hxx>
37
38 // #i73264#
39 #include <basegfx/matrix/b2dhommatrix.hxx>
40 #include <osl/file.hxx>
41
42 #include <vector>
43 #include <stack>
44 #include <map>
45
46 #ifdef AUGUSTUS
47 #include "lame.h"
48 #include "sndfile.h"
49 #endif
50
51 #include <stdio.h>
52
53 class GDIMetaFile;
54 class BitmapEx;
55 class PolyPolygon;
56 class Gradient;
57 class SvtGraphicFill;
58 class SvtGraphicStroke;
59 class LineInfo;
60 namespace basegfx { class B2DPolygon; }
61
_uInt16(sal_Int32 nValue)62 inline sal_uInt16 _uInt16( sal_Int32 nValue )
63 {
64 OSL_ENSURE( (nValue >= 0) && ((sal_uInt32)nValue <= 0xffff), "overflow while converting sal_Int32 to sal_uInt16" );
65 return (sal_uInt16)nValue;
66 }
67
_Int16(sal_Int32 nValue)68 inline sal_Int16 _Int16( sal_Int32 nValue )
69 {
70 OSL_ENSURE( (nValue >= -32768) && (nValue <= 32767), "overflow while converting sal_Int32 to sal_Int16" );
71 return (sal_Int16)nValue;
72 }
73
74 class VirtualDevice;
75
76 namespace swf {
77
78 const sal_uInt8 TAG_END = 0;
79 const sal_uInt8 TAG_SHOWFRAME = 1;
80
81 const sal_uInt8 TAG_DEFINEBUTTON = 7;
82
83 const sal_uInt8 TAG_BACKGROUNDCOLOR = 9;
84
85 const sal_uInt8 TAG_DOACTION = 12;
86 const sal_uInt8 TAG_STARTSOUND = 15;
87
88 const sal_uInt8 TAG_SOUNDSTREAMBLOCK = 19;
89 const sal_uInt8 TAG_SOUNDSTREAMHEAD = 18;
90 const sal_uInt8 TAG_SOUNDSTREAMHEAD2 = 45;
91
92 const sal_uInt8 TAG_JPEGTABLES = 8;
93 const sal_uInt8 TAG_DEFINEBITS = 6;
94 const sal_uInt8 TAG_DEFINEBITSLOSSLESS = 20;
95 const sal_uInt8 TAG_DEFINEBITSJPEG2 = 21;
96 const sal_uInt8 TAG_DEFINEBITSJPEG3 = 35;
97 const sal_uInt8 TAG_DEFINEBITSLOSSLESS2 = 36;
98 const sal_uInt8 TAG_DEFINEEDITTEXT= 37;
99 const sal_uInt8 TAG_PLACEOBJECT = 4;
100 const sal_uInt8 TAG_PLACEOBJECT2 = 26;
101 const sal_uInt8 TAG_REMOVEOBJECT2 = 28;
102
103 const sal_uInt8 TAG_DEFINEFONT = 10;
104 const sal_uInt8 TAG_DEFINETEXT = 11;
105 const sal_uInt8 TAG_DEFINESHAPE3 = 32;
106 const sal_uInt8 TAG_DEFINESPRITE = 39;
107
108 const sal_uInt8 TAG_FRAMELABEL = 43;
109
110 const sal_uInt8 TAG_HEADER = 0xff;
111
112 ///////////////////////////////////////////////////////////////////////
113
114 /** converts a double to a 16.16 flash fixed value */
115 sal_uInt32 getFixed( double fValue );
116
117 ///////////////////////////////////////////////////////////////////////
118
119 typedef ::std::map<sal_uInt32, sal_uInt16> ChecksumCache;
120
121 /** unsigned int 16 compare operation for stl */
122 struct ltuint16
123 {
operator ()swf::ltuint16124 bool operator()(sal_uInt16 s1, sal_uInt16 s2) const
125 {
126 return s1 < s2;
127 }
128 };
129
130 ///////////////////////////////////////////////////////////////////////
131
132 /** container class to create bit structures */
133 class BitStream
134 {
135 public:
136 BitStream();
137
138 void writeUB( sal_uInt32 nValue, sal_uInt16 nBits );
139 void writeSB( sal_Int32 nValue, sal_uInt16 nBits );
140 void writeFB( sal_uInt32 nValue, sal_uInt16 nBits );
141
142 void pad();
143 void writeTo( SvStream& out );
144
145 sal_uInt32 getOffset() const;
146 private:
147
148 std::vector< sal_uInt8 > maData;
149 sal_uInt8 mnBitPos;
150 sal_uInt8 mnCurrentByte;
151 };
152
153 ///////////////////////////////////////////////////////////////////////
154
155 /** this class collects all used glyphs for a given fonts and maps
156 characters to glyph ids.
157 */
158 class FlashFont
159 {
160 public:
161 FlashFont( const Font& rFont, sal_uInt16 nId );
162 ~FlashFont();
163
164 sal_uInt16 getGlyph( sal_uInt16 nChar, VirtualDevice* pVDev );
165
166 void write( SvStream& out );
167
getID() const168 sal_uInt16 getID() const { return mnId; }
getFont()169 const Font& getFont() { return maFont; }
170
171 private:
172 const Font maFont;
173 std::map<sal_uInt16, sal_uInt16, ltuint16> maGlyphIndex;
174 sal_uInt16 mnNextIndex;
175 sal_uInt16 mnId;
176 BitStream maGlyphData;
177 std::vector< sal_uInt16 > maGlyphOffsets;
178 };
179
180 typedef std::vector<FlashFont*> FontMap;
181
182 ///////////////////////////////////////////////////////////////////////
183
184 /** this class helps creating flash tags */
185 class Tag : public SvMemoryStream
186 {
187 public:
188 Tag( sal_uInt8 nTagId );
189
getTagId() const190 sal_uInt8 getTagId() const { return mnTagId; }
191
192 void write( SvStream& out );
193
194 void addUI32( sal_uInt32 nValue );
195 //unused as of yet void addI32( sal_Int32 nValue );
196 void addUI16( sal_uInt16 nValue );
197 //unused as of yet void addI16( sal_Int16 nValue );
198 void addUI8( sal_uInt8 nValue );
199 void addBits( BitStream& rIn );
200
201 void addRGBA( const Color& rColor );
202 void addRGB( const Color& rColor );
203 void addRect( const Rectangle& rRect );
204 void addMatrix( const ::basegfx::B2DHomMatrix& rMatrix ); // #i73264#
205 void addString( const char* pString );
206 void addStream( SvStream& rIn );
207
208 static void writeMatrix( SvStream& rOut, const ::basegfx::B2DHomMatrix& rMatrix ); // #i73264#
209 static void writeRect( SvStream& rOut, const Rectangle& rRect );
210
211 private:
212 sal_uInt8 mnTagId;
213 };
214
215 ///////////////////////////////////////////////////////////////////////
216
217 /** this class helps to define flash sprites */
218 class Sprite
219 {
220 public:
221 Sprite( sal_uInt16 nId );
222 ~Sprite();
223
224 void write( SvStream& out );
225
getId() const226 sal_uInt16 getId() const { return mnId; }
227
228 void addTag( Tag* pNewTag );
229
230 private:
231 std::vector< Tag* > maTags;
232 sal_uInt16 mnId;
233 sal_uInt32 mnFrames;
234 };
235
236 ///////////////////////////////////////////////////////////////////////
237
238 /** this class stores a flash fill style for shapes */
239 class FillStyle
240 {
241 public:
242 enum FillStyleType { solid = 0x00, linear_gradient = 0x10, radial_gradient = 0x12, tiled_bitmap = 0x40, clipped_bitmap = 0x41 };
243
244 /** this c'tor creates a solid fill style */
245 FillStyle( const Color& rSolidColor );
246
247 /** this c'tor creates a linear or radial gradient fill style */
248 FillStyle( const Rectangle& rBoundRect, const Gradient& rGradient );
249
250 /** this c'tor creates a tiled or clipped bitmap fill style */
251 FillStyle( sal_uInt16 nBitmapId, bool bClipped, const ::basegfx::B2DHomMatrix& rMatrix ); // #i73264#
252
253 void addTo( Tag* pTag ) const;
254
255 private:
256 void Impl_addGradient( Tag* pTag ) const;
257
258 FillStyleType meType;
259 ::basegfx::B2DHomMatrix maMatrix; // #i73264#
260 sal_uInt16 mnBitmapId;
261 Color maColor;
262 Gradient maGradient;
263 Rectangle maBoundRect;
264 };
265
266 ///////////////////////////////////////////////////////////////////////
267
268 /** this class creates a flash movie from vcl geometry */
269 class Writer
270 {
271 friend class FlashFont;
272
273 public:
274 /** creates a writer for a new flash movie.
275 nDocWidth and nDocHeight are the dimensions of the movie.
276 They must be in 100th/mm.
277
278 An invisible shape with the size of the document is placed at depth 1
279 and it clips all shapes on depth 2 and 3.
280 */
281 Writer( sal_Int32 nDocWidthInput, sal_Int32 nDocHeightInput, sal_Int32 nDocWidth, sal_Int32 nDocHeight, sal_Int32 nJPEGcompressMode = -1 );
282 ~Writer();
283
284 void storeTo( com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > &xOutStream );
285
286 // geometry
287 void setClipping( const PolyPolygon* pClipPolyPolygon );
288
289 /** defines a flash shape from a filled polygon.
290 The coordinates must be in twips */
291 sal_uInt16 defineShape( const Polygon& rPoly, const FillStyle& rFillStyle );
292
293 /** defines a flash shape from a filled polypolygon.
294 The coordinates must be in twips */
295 sal_uInt16 defineShape( const PolyPolygon& rPolyPoly, const FillStyle& rFillStyle );
296
297 /** defines a flash shape from a outlined polypolygon.
298 The coordinates must be in twips */
299 sal_uInt16 defineShape( const PolyPolygon& rPolyPoly, sal_uInt16 nLineWidth, const Color& rLineColor );
300
301 /** defines a flash shape from a vcl metafile.
302 The mapmode of the metafile is used to map all coordinates to twips.
303 A character id of a flash sprite is returned that contains all geometry
304 from the metafile.
305 */
306 sal_uInt16 defineShape( const GDIMetaFile& rMtf, sal_Int16 x = 0, sal_Int16 y = 0 );
307
308 /** defines a bitmap and returns its flash id.
309 */
310 sal_uInt16 defineBitmap( const BitmapEx& bmpSource, sal_Int32 nJPEGQualityLevel );
311
312 // control tags
313
314 /** inserts a place shape tag into the movie stream or the current sprite */
315 void placeShape( sal_uInt16 nID, sal_uInt16 nDepth, sal_Int32 x, sal_Int32 y, sal_uInt16 nClipDepth = 0, const char* pName = NULL );
316
317 #ifdef THEFUTURE
318 /** inserts a move shape tag into the movie stream or the current sprite */
319 void moveShape( sal_uInt16 nDepth, sal_Int32 x, sal_Int32 y );
320 #endif
321
322 /** inserts a remove shape tag into the movie stream or the current sprite */
323 void removeShape( sal_uInt16 nDepth );
324
325 /** inserts a show frame tag into the movie stream or the current sprite */
326 void showFrame();
327
328 /** creates a new sprite and sets it as the current sprite for editing.
329 Only one sprite can be edited at one time */
330 sal_uInt16 startSprite();
331
332 /** ends editing of the curent sprites and adds it to the movie stream */
333 void endSprite();
334
335 /** inserts a doaction tag with an ActionStop */
336 void stop();
337
338 /** inserts a doaction tag with an ActionStop, place a button on depth nDepth that
339 continues playback on click */
340 void waitOnClick( sal_uInt16 nDepth );
341
342 /** inserts a doaction tag with an ActionGotoFrame */
343 void gotoFrame( sal_uInt16 nFrame );
344
345 #ifdef AUGUSTUS
346 /** stream out a sound. Should make it more intelligent so it interleaves with other items.*/
347 sal_Bool streamSound( const char * filename );
348 #endif
349
350 private:
351 Point map( const Point& rPoint ) const;
352 Size map( const Size& rSize ) const;
353 void map( PolyPolygon& rPolyPolygon ) const;
354 sal_Int32 mapRelative( sal_Int32 n100thMM ) const;
355
356 void startTag( sal_uInt8 nTagId );
357 void endTag();
358 sal_uInt16 createID();
359
360 void Impl_writeBmp( sal_uInt16 nBitmapId, sal_uInt32 width, sal_uInt32 height, sal_uInt8 *pCompressed, sal_uInt32 compressed_size );
361 void Impl_writeImage( const BitmapEx& rBmpEx, const Point& rPt, const Size& rSz, const Point& rSrcPt, const Size& rSrcSz, const Rectangle& rClipRect, bool bMap );
362 void Impl_writeJPEG(sal_uInt16 nBitmapId, const sal_uInt8* pJpgData, sal_uInt32 nJpgDataLength, sal_uInt8 *pCompressed, sal_uInt32 compressed_size );
363 void Impl_handleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon);
364 void Impl_writeActions( const GDIMetaFile& rMtf );
365 void Impl_writePolygon( const Polygon& rPoly, sal_Bool bFilled );
366 void Impl_writePolygon( const Polygon& rPoly, sal_Bool bFilled, const Color& rFillColor, const Color& rLineColor );
367 void Impl_writePolyPolygon( const PolyPolygon& rPolyPoly, sal_Bool bFilled, sal_uInt8 nTransparence = 0);
368 void Impl_writePolyPolygon( const PolyPolygon& rPolyPoly, sal_Bool bFilled, const Color& rFillColor, const Color& rLineColor );
369 void Impl_writeText( const Point& rPos, const String& rText, const sal_Int32* pDXArray, long nWidth );
370 void Impl_writeText( const Point& rPos, const String& rText, const sal_Int32* pDXArray, long nWidth, Color aTextColor );
371 void Impl_writeGradientEx( const PolyPolygon& rPolyPoly, const Gradient& rGradient );
372 void Impl_writeLine( const Point& rPt1, const Point& rPt2, const Color* pLineColor = NULL );
373 void Impl_writeRect( const Rectangle& rRect, long nRadX, long nRadY );
374 void Impl_writeEllipse( const Point& rCenter, long nRadX, long nRadY );
375 bool Impl_writeFilling( SvtGraphicFill& rFilling );
376 bool Impl_writeStroke( SvtGraphicStroke& rStroke );
377
378 FlashFont& Impl_getFont( const Font& rFont );
379
380 static void Impl_addPolygon( BitStream& rBits, const Polygon& rPoly, sal_Bool bFilled );
381
382 static void Impl_addShapeRecordChange( BitStream& rBits, sal_Int16 dx, sal_Int16 dy, sal_Bool bFilled );
383 static void Impl_addStraightEdgeRecord( BitStream& rBits, sal_Int16 dx, sal_Int16 dy );
384 static void Impl_addCurvedEdgeRecord( BitStream& rBits, sal_Int16 control_dx, sal_Int16 control_dy, sal_Int16 anchor_dx, sal_Int16 anchor_dy );
385 static void Impl_addEndShapeRecord( BitStream& rBits );
386
387 static void Impl_addStraightLine( BitStream& rBits,
388 Point& rLastPoint,
389 const double P2x, const double P2y );
390 static void Impl_addQuadBezier( BitStream& rBits,
391 Point& rLastPoint,
392 const double P2x, const double P2y,
393 const double P3x, const double P3y );
394 static void Impl_quadBezierApprox( BitStream& rBits,
395 Point& rLastPoint,
396 const double d2,
397 const double P1x, const double P1y,
398 const double P2x, const double P2y,
399 const double P3x, const double P3y,
400 const double P4x, const double P4y );
401
402 com::sun::star::uno::Reference < com::sun::star::i18n::XBreakIterator > Impl_GetBreakIterator();
403
404 private:
405 com::sun::star::uno::Reference< com::sun::star::i18n::XBreakIterator > mxBreakIterator;
406
407 FontMap maFonts;
408
409 sal_Int32 mnDocWidth;
410 sal_Int32 mnDocHeight;
411
412 // AS: Scaling factor for output.
413 double mnDocXScale;
414 double mnDocYScale;
415
416 sal_uInt16 mnWhiteBackgroundShapeId;
417 sal_uInt16 mnPageButtonId;
418
419 VirtualDevice* mpVDev;
420
421 const PolyPolygon* mpClipPolyPolygon;
422
423 /** holds the informations of the objects defined in the movie stream
424 while executing defineShape
425 */
426 typedef std::vector<sal_uInt16> CharacterIdVector;
427 CharacterIdVector maShapeIds;
428
429 Tag* mpTag;
430 Sprite* mpSprite;
431 std::stack<Sprite*> mvSpriteStack;
432 ChecksumCache mBitmapCache;
433
434 sal_uInt16 mnNextId;
435 sal_uInt32 mnFrames;
436
437 // com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > mxOutStream;
438 oslFileHandle mxOutStream;
439
440 utl::TempFile maMovieTempFile;
441 utl::TempFile maFontsTempFile;
442
443 SvStream* mpMovieStream;
444 SvStream* mpFontsStream;
445
446 #ifdef AUGUSTUS
447 lame_global_flags *m_lame_flags;
448 #endif
449
450 sal_uInt8 mnGlobalTransparency;
451 sal_Int32 mnJPEGCompressMode;
452 };
453
454 ///////////////////////////////////////////////////////////////////////
455
456 }
457
458 #endif
459