xref: /AOO41X/main/filter/source/flash/swfwriter.hxx (revision 22e87013b212da8c80c93e291ad90de8f36964c2)
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