summaryrefslogtreecommitdiff
path: root/filter/source/flash/swfwriter.hxx
blob: 215777bfef2694f3b0a41332d754fee9b52ebd25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_FILTER_SOURCE_FLASH_SWFWRITER_HXX
#define INCLUDED_FILTER_SOURCE_FLASH_SWFWRITER_HXX

#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/i18n/XBreakIterator.hpp>
#include <vcl/checksum.hxx>
#include <vcl/font.hxx>
#include <vcl/gradient.hxx>
#include <vcl/vclptr.hxx>
#include <unotools/tempfile.hxx>
#include <tools/color.hxx>
#include <tools/poly.hxx>
#include <tools/gen.hxx>
#include <tools/stream.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <osl/file.hxx>

#include <vector>
#include <stack>
#include <map>

class GDIMetaFile;
class BitmapEx;
namespace tools { class PolyPolygon; }
class Gradient;
class SvtGraphicFill;
class SvtGraphicStroke;
class LineInfo;
namespace basegfx { class B2DPolygon; }

inline sal_uInt16 _uInt16( sal_Int32 nValue )
{
    OSL_ENSURE( (nValue >= 0) && ((sal_uInt32)nValue <= 0xffff), "overflow while converting sal_Int32 to sal_uInt16" );
    return (sal_uInt16)nValue;
}

inline sal_Int16 _Int16( sal_Int32 nValue )
{
    OSL_ENSURE( (nValue >= -32768) && (nValue <= 32767), "overflow while converting sal_Int32 to sal_Int16" );
    return (sal_Int16)nValue;
}

class VirtualDevice;

sal_uInt16 getMaxBitsSigned( sal_Int32 nValue );

namespace swf {

const sal_uInt8 TAG_END             = 0;
const sal_uInt8 TAG_SHOWFRAME       = 1;

const sal_uInt8 TAG_DEFINEBUTTON    = 7;

const sal_uInt8 TAG_BACKGROUNDCOLOR = 9;

const sal_uInt8 TAG_DOACTION        = 12;
const sal_uInt8 TAG_STARTSOUND      = 15;

const sal_uInt8 TAG_SOUNDSTREAMBLOCK = 19;
const sal_uInt8 TAG_SOUNDSTREAMHEAD = 18;
const sal_uInt8 TAG_SOUNDSTREAMHEAD2 = 45;

const sal_uInt8 TAG_JPEGTABLES      = 8;
const sal_uInt8 TAG_DEFINEBITS      = 6;
const sal_uInt8 TAG_DEFINEBITSLOSSLESS = 20;
const sal_uInt8 TAG_DEFINEBITSJPEG2 = 21;
const sal_uInt8 TAG_DEFINEBITSJPEG3 = 35;
const sal_uInt8 TAG_DEFINEBITSLOSSLESS2 = 36;
const sal_uInt8 TAG_DEFINEEDITTEXT= 37;
const sal_uInt8 TAG_PLACEOBJECT     = 4;
const sal_uInt8 TAG_PLACEOBJECT2    = 26;
const sal_uInt8 TAG_REMOVEOBJECT2   = 28;

const sal_uInt8 TAG_DEFINEFONT      = 10;
const sal_uInt8 TAG_DEFINETEXT      = 11;
const sal_uInt8 TAG_DEFINESHAPE3    = 32;
const sal_uInt8 TAG_DEFINESPRITE    = 39;

const sal_uInt8 TAG_FRAMELABEL      = 43;

const sal_uInt8 TAG_HEADER          = 0xff;



/** converts a double to a 16.16 flash fixed value */
sal_uInt32 getFixed( double fValue );



typedef ::std::map<BitmapChecksum, sal_uInt16> ChecksumCache;

/** unsigned int 16 compare operation for stl */
struct ltuint16
{
  bool operator()(sal_uInt16 s1, sal_uInt16 s2) const
  {
    return s1 < s2;
  }
};



/** container class to create bit structures */
class BitStream
{
public:
    BitStream();

    void writeUB( sal_uInt32 nValue, sal_uInt16 nBits );
    void writeSB( sal_Int32 nValue, sal_uInt16 nBits );
    void writeFB( sal_uInt32 nValue, sal_uInt16 nBits );

    void pad();
    void writeTo( SvStream& out );

    sal_uInt32 getOffset() const;
private:

    std::vector< sal_uInt8 > maData;
    sal_uInt8 mnBitPos;
    sal_uInt8 mnCurrentByte;
};



/** this class collects all used glyphs for a given fonts and maps
    characters to glyph ids.
*/
class FlashFont
{
public:
    FlashFont( const vcl::Font& rFont, sal_uInt16 nId );
    ~FlashFont();

    sal_uInt16 getGlyph( sal_uInt16 nChar, VirtualDevice* pVDev );

    void write( SvStream& out );

    sal_uInt16 getID() const { return mnId; }
    const vcl::Font& getFont() { return maFont; }

private:
    const vcl::Font maFont;
    std::map<sal_uInt16, sal_uInt16, ltuint16> maGlyphIndex;
    sal_uInt16 mnNextIndex;
    sal_uInt16 mnId;
    BitStream maGlyphData;
    std::vector< sal_uInt16 > maGlyphOffsets;
};

typedef std::vector<FlashFont*> FontMap;



/** this class helps creating flash tags */
class Tag : public SvMemoryStream
{
public:
    Tag( sal_uInt8 nTagId );

    sal_uInt8 getTagId() const { return mnTagId; }

    void write( SvStream& out );

    void addUI32( sal_uInt32 nValue );
    void addUI16( sal_uInt16 nValue );
    void addUI8( sal_uInt8 nValue );
    void addBits( BitStream& rIn );

    void addRGBA( const Color& rColor );
    void addRGB( const Color& rColor );
    void addRect( const Rectangle& rRect );
    void addMatrix( const ::basegfx::B2DHomMatrix& rMatrix ); // #i73264#
    void addString( const char* pString );
    void addStream( SvStream& rIn );

    static void writeMatrix( SvStream& rOut, const ::basegfx::B2DHomMatrix& rMatrix ); // #i73264#
    static void writeRect( SvStream& rOut, const Rectangle& rRect );

private:
    sal_uInt8 mnTagId;
};



/** this class helps to define flash sprites */
class Sprite
{
public:
    Sprite( sal_uInt16 nId );
    ~Sprite();

    void write( SvStream& out );

    sal_uInt16 getId() const { return mnId; }

    void addTag( Tag* pNewTag );

private:
    std::vector< Tag* > maTags;
    sal_uInt16  mnId;
    sal_uInt32  mnFrames;
};



/** this class stores a flash fill style for shapes */
class FillStyle
{
public:
    enum FillStyleType { solid = 0x00, linear_gradient = 0x10, radial_gradient = 0x12, tiled_bitmap = 0x40, clipped_bitmap = 0x41 };

    /** this c'tor creates a solid fill style */
    FillStyle( const Color& rSolidColor );

    /** this c'tor creates a linear or radial gradient fill style */
    FillStyle( const Rectangle& rBoundRect, const Gradient& rGradient );

    /** this c'tor creates a tiled or clipped bitmap fill style */
    FillStyle( sal_uInt16 nBitmapId, bool bClipped, const ::basegfx::B2DHomMatrix& rMatrix ); // #i73264#

    void addTo( Tag* pTag ) const;

private:
    void Impl_addGradient( Tag* pTag ) const;

    FillStyleType   meType;
    ::basegfx::B2DHomMatrix     maMatrix; // #i73264#
    sal_uInt16      mnBitmapId;
    Color           maColor;
    Gradient        maGradient;
    Rectangle       maBoundRect;
};



/** this class creates a flash movie from vcl geometry */
class Writer
{
    friend class FlashFont;

public:
    /** creates a writer for a new flash movie.
        nDocWidth and nDocHeight are the dimensions of the movie.
        They must be in 100th/mm.

        An invisible shape with the size of the document is placed at depth 1
        and it clips all shapes on depth 2 and 3.
    */
    Writer( sal_Int32 nDocWidthInput, sal_Int32 nDocHeightInput, sal_Int32 nDocWidth, sal_Int32 nDocHeight, sal_Int32 nJPEGcompressMode = -1 );
    ~Writer();

    void storeTo( com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > &xOutStream );

    // geometry
    void setClipping( const tools::PolyPolygon* pClipPolyPolygon );

    /** defines a flash shape from a filled polygon.
        The coordinates must be in twips */
    sal_uInt16 defineShape( const Polygon& rPoly, const FillStyle& rFillStyle );

    /** defines a flash shape from a filled polypolygon.
        The coordinates must be in twips */
    sal_uInt16 defineShape( const tools::PolyPolygon& rPolyPoly, const FillStyle& rFillStyle );

    /** defines a flash shape from a outlined polypolygon.
        The coordinates must be in twips */
    sal_uInt16 defineShape( const tools::PolyPolygon& rPolyPoly, sal_uInt16 nLineWidth, const Color& rLineColor );

    /** defines a flash shape from a vcl metafile.
        The mapmode of the metafile is used to map all coordinates to twips.
        A character id of a flash sprite is returned that contains all geometry
        from the metafile.
    */
    sal_uInt16 defineShape( const GDIMetaFile& rMtf, sal_Int16 x = 0, sal_Int16 y = 0 );

    /** defines a bitmap and returns its flash id.
    */
    sal_uInt16 defineBitmap( const BitmapEx& bmpSource, sal_Int32 nJPEGQualityLevel  );

    // control tags

    /** inserts a place shape tag into the movie stream or the current sprite */
    void placeShape( sal_uInt16 nID, sal_uInt16 nDepth, sal_Int32 x, sal_Int32 y, sal_uInt16 nClipDepth = 0, const char* pName = NULL );

    /** inserts a remove shape tag into the movie stream or the current sprite */
    void removeShape( sal_uInt16 nDepth );

    /** inserts a show frame tag into the movie stream or the current sprite */
    void showFrame();

    /** creates a new sprite and sets it as the current sprite for editing.
        Only one sprite can be edited at one time */
    sal_uInt16 startSprite();

    /** ends editing of the current sprites and adds it to the movie stream */
    void endSprite();

    /** inserts a doaction tag with an ActionStop */
    void stop();

    /** inserts a doaction tag with an ActionStop, place a button on depth nDepth that
        continues playback on click */
    void waitOnClick( sal_uInt16 nDepth );

    /** inserts a doaction tag with an ActionGotoFrame */
    void gotoFrame( sal_uInt16 nFrame );

private:
    Point                   map( const Point& rPoint ) const;
    Size                    map( const Size& rSize ) const;
    void                    map( tools::PolyPolygon& rPolyPolygon ) const;
    sal_Int32               mapRelative( sal_Int32 n100thMM ) const;

    void startTag( sal_uInt8 nTagId );
    void endTag();
    sal_uInt16 createID() { return mnNextId++; }

    void Impl_writeBmp( sal_uInt16 nBitmapId, sal_uInt32 width, sal_uInt32 height, sal_uInt8 *pCompressed, sal_uInt32 compressed_size );
    void Impl_writeImage( const BitmapEx& rBmpEx, const Point& rPt, const Size& rSz, const Point& rSrcPt, const Size& rSrcSz, const Rectangle& rClipRect, bool bMap );
    void Impl_writeJPEG(sal_uInt16 nBitmapId, const sal_uInt8* pJpgData, sal_uInt32 nJpgDataLength, sal_uInt8 *pCompressed, sal_uInt32 compressed_size );
    void Impl_handleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon);
    void Impl_writeActions( const GDIMetaFile& rMtf );
    void Impl_writePolygon( const Polygon& rPoly, bool bFilled );
    void Impl_writePolygon( const Polygon& rPoly, bool bFilled, const Color& rFillColor, const Color& rLineColor );
    void Impl_writePolyPolygon( const tools::PolyPolygon& rPolyPoly, bool bFilled, sal_uInt8 nTransparence = 0);
    void Impl_writePolyPolygon( const tools::PolyPolygon& rPolyPoly, bool bFilled, const Color& rFillColor, const Color& rLineColor );
    void Impl_writeText( const Point& rPos, const OUString& rText, const long* pDXArray, long nWidth );
    void Impl_writeText( const Point& rPos, const OUString& rText, const long* pDXArray, long nWidth, Color aTextColor );
    void Impl_writeGradientEx( const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient );
    void Impl_writeLine( const Point& rPt1, const Point& rPt2, const Color* pLineColor = NULL );
    void Impl_writeRect( const Rectangle& rRect, long nRadX, long nRadY );
    void Impl_writeEllipse( const Point& rCenter, long nRadX, long nRadY );
    bool Impl_writeFilling( SvtGraphicFill& rFilling );
    bool Impl_writeStroke( SvtGraphicStroke& rStroke );

    FlashFont& Impl_getFont( const vcl::Font& rFont );

    static void Impl_addPolygon( BitStream& rBits, const Polygon& rPoly, bool bFilled );

    static void Impl_addShapeRecordChange( BitStream& rBits, sal_Int16 dx, sal_Int16 dy, bool bFilled );
    static void Impl_addStraightEdgeRecord( BitStream& rBits, sal_Int16 dx, sal_Int16 dy );
    static void Impl_addCurvedEdgeRecord( BitStream& rBits, sal_Int16 control_dx, sal_Int16 control_dy, sal_Int16 anchor_dx, sal_Int16 anchor_dy );
    static void Impl_addEndShapeRecord( BitStream& rBits );

    static void Impl_addStraightLine( BitStream& rBits,
                                  Point& rLastPoint,
                                  const double P2x, const double P2y );
    static void Impl_addQuadBezier( BitStream& rBits,
                                Point& rLastPoint,
                                const double P2x, const double P2y,
                                const double P3x, const double P3y );
    static void Impl_quadBezierApprox( BitStream& rBits,
                                   Point& rLastPoint,
                                   const double d2,
                                   const double P1x, const double P1y,
                                   const double P2x, const double P2y,
                                   const double P3x, const double P3y,
                                   const double P4x, const double P4y );

    com::sun::star::uno::Reference < com::sun::star::i18n::XBreakIterator > Impl_GetBreakIterator();

private:
    com::sun::star::uno::Reference< com::sun::star::i18n::XBreakIterator > mxBreakIterator;

    FontMap                 maFonts;

    sal_Int32 mnDocWidth;
    sal_Int32 mnDocHeight;

    // AS: Scaling factor for output.
    double mnDocXScale;
    double mnDocYScale;

    sal_uInt16 mnWhiteBackgroundShapeId;
    sal_uInt16 mnPageButtonId;

    VclPtrInstance<VirtualDevice> mpVDev;

    const tools::PolyPolygon* mpClipPolyPolygon;

    /** holds the information of the objects defined in the movie stream
        while executing defineShape
    */
    typedef std::vector<sal_uInt16> CharacterIdVector;
    CharacterIdVector       maShapeIds;

    Tag* mpTag;
    Sprite* mpSprite;
    std::stack<Sprite*> mvSpriteStack;
    ChecksumCache mBitmapCache;

    sal_uInt16 mnNextId;
    sal_uInt32  mnFrames;

//  com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > mxOutStream;
    oslFileHandle mxOutStream;

    utl::TempFile maMovieTempFile;
    utl::TempFile maFontsTempFile;

    SvStream* mpMovieStream;
    SvStream* mpFontsStream;

    sal_uInt8 mnGlobalTransparency;
    sal_Int32 mnJPEGCompressMode;
};



}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */