xref: /trunk/main/filter/source/flash/swfwriter.hxx (revision 8b7f65dd)
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 current 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