File indexing completed on 2024-04-21 04:54:04

0001 /*
0002     SPDX-FileCopyrightText: 2005-2007 Koos Vriezen <koos.vriezen@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef _KMPLAYER_SMILL_H_
0008 #define _KMPLAYER_SMILL_H_
0009 
0010 #include "config-kmplayer.h"
0011 #include <QString>
0012 #include <QStringList>
0013 
0014 #include "kmplayerplaylist.h"
0015 #include "surface.h"
0016 
0017 struct TransTypeInfo;
0018 
0019 namespace KMPlayer {
0020 
0021 class ImageMedia;
0022 class Expression;
0023 
0024 /*
0025  * Interpretation of sizes
0026  */
0027 class SizeType
0028 {
0029 public:
0030     SizeType ();
0031     SizeType (const QString & s, bool force_perc=false);
0032     void reset ();
0033     SizeType & operator = (const QString & s);
0034     SizeType & operator = (Single d);
0035     SizeType & operator += (const SizeType & s);
0036     SizeType & operator -= (const SizeType & s);
0037     SizeType & operator /= (const int i)
0038         { perc_size /= i; abs_size /= i; return *this; }
0039     SizeType & operator *= (const float f)
0040         { perc_size *= f; abs_size *= f; return *this; }
0041     Single size (Single relative_to = 100) const;
0042     bool isSet () const { return isset; }
0043     QString toString () const;
0044 private:
0045     Single perc_size;
0046     Single abs_size;
0047     bool isset;
0048     bool has_percentage;
0049 };
0050 
0051 /**
0052  * For RegPoint, Region and MediaType, having sizes
0053  */
0054 class CalculatedSizer
0055 {
0056 public:
0057     CalculatedSizer () {}
0058     ~CalculatedSizer () {}
0059 
0060     void resetSizes ();
0061     void calcSizes (Node *, CalculatedSizer *region_sz, Single w, Single h,
0062             Single & xoff, Single & yoff, Single & w1, Single & h1);
0063     bool applyRegPoints (Node *, CalculatedSizer *region_sz, Single w, Single h,
0064             Single & xoff, Single & yoff, Single & w1, Single & h1);
0065     SizeType left, top, width, height, right, bottom;
0066     QString reg_point, reg_align;
0067     bool setSizeParam (const TrieString &name, const QString &value);
0068     void move (const SizeType &x, const SizeType &y);
0069 };
0070 
0071 /**
0072  * Live representation of a SMIL element having timings
0073  */
0074 class Runtime
0075 {
0076 public:
0077     enum TimingState {
0078         TimingsInit = 0, TimingsInitialized, TimingsDisabled,
0079         timings_began, timings_started, TimingsTransIn, timings_paused,
0080         timings_stopped, timings_freezed
0081     };
0082     enum Fill {
0083         fill_default, fill_inherit, fill_remove, fill_freeze,
0084         fill_hold, fill_transition, fill_auto
0085     };
0086     enum DurationTime { BeginTime = 0, DurTime, EndTime, DurTimeLast };
0087     enum Duration {
0088         DurIndefinite = -1,
0089         DurTimer = (int) MsgEventTimer,
0090         DurActivated = (int) MsgEventClicked,
0091         DurInBounds = (int) MsgEventPointerInBounds,
0092         DurOutBounds = (int) MsgEventPointerOutBounds,
0093         DurStart = (int) MsgEventStarted,
0094         DurEnd = (int) MsgEventStopped,
0095         DurMedia = (int)MsgMediaFinished,
0096         DurStateChanged = (int)MsgStateChanged,
0097         DurAccessKey = (int)MsgAccessKey,
0098         DurTransition,
0099         DurLastDuration
0100     };
0101     Runtime (Element *e);
0102     ~Runtime ();
0103     /**
0104      * Called when element is pulled in scope, from Node::activate()
0105      */
0106     void start ();
0107     void tryFinish () { propagateStop (false); }
0108     void doFinish () { propagateStop (true); }
0109     void finish ();
0110     void startAndBeginNode (); // skip start timer (if any)
0111     /**
0112      * Reset all data, called from end() and init()
0113      */
0114     void init ();
0115     void initialize ();
0116     bool parseParam (const TrieString & name, const QString & value);
0117     TimingState state () const { return timingstate; }
0118     void message (MessageType msg, void *content=nullptr);
0119     void *role (RoleType msg, void *content=nullptr);
0120     /**
0121      * Duration items, begin/dur/end, length information or connected element
0122      */
0123     struct DurationItem {
0124         DurationItem ();
0125         DurationItem &operator = (const DurationItem &other);
0126         bool matches (const Duration dur, const Posting *post);
0127         void clear();
0128         Duration durval;
0129         int offset;
0130         VirtualVoid *payload;
0131         ConnectionLink connection;
0132         DurationItem *next;
0133     } durations [(int) DurTimeLast];
0134     void setDuration ();
0135     bool started () const;
0136     bool active () const {
0137         return timingstate >= timings_started && timingstate != timings_stopped;
0138     }
0139     void stopped ();
0140     DurationItem & beginTime () { return durations[BeginTime]; }
0141     DurationItem & durTime () { return durations[DurTime]; }
0142     DurationItem & endTime () { return durations [EndTime]; }
0143 
0144     TimingState timingstate;
0145     TimingState unpaused_state;
0146     int repeat_count;
0147     QString expr;
0148     ConnectionList m_StartListeners;        // Element about to be started
0149     ConnectionList m_StartedListeners;      // Element is started
0150     ConnectionList m_StoppedListeners;      // Element stopped
0151     Posting *begin_timer;
0152     Posting *duration_timer;
0153     Posting *started_timer;
0154     Posting *stopped_timer;
0155     NodePtrW paused_by;
0156     unsigned int start_time;
0157     unsigned int finish_time;
0158     unsigned int paused_time;
0159     Fill fill;
0160     Fill fill_def;
0161     Fill fill_active;
0162     Element *element;
0163     int trans_in_dur;
0164 private:
0165     void propagateStop (bool forced);
0166     void propagateStart ();
0167     int repeat;
0168 };
0169 
0170 class MouseListeners
0171 {
0172 public:
0173     MouseListeners();
0174 
0175     ConnectionList *receivers (MessageType msg);
0176 
0177     ConnectionList m_ActionListeners;      // mouse clicked
0178     ConnectionList m_OutOfBoundsListeners; // mouse left
0179     ConnectionList m_InBoundsListeners;    // mouse entered
0180 };
0181 
0182 /**
0183  * Translates string to centi-seconds or 'special' high number
0184  */
0185 bool parseTime (const QString & val, int & dur /*,const QString & dateformat*/);
0186 
0187 class SmilTextProperties
0188 {
0189 public:
0190     enum Align { AlignInherit, AlignLeft, AlignCenter, AlignRight };
0191     enum FontWeight { WeightNormal, WeightBold, WeightInherit };
0192     enum Spacing { SpaceDefault, SpacePreserve };
0193     enum Style {
0194         StyleNormal, StyleItalic, StyleOblique, StyleRevOblique, StyleInherit
0195     };
0196     enum TextDirection { DirLtr, DirRtl, DirLtro, DirRtlo, DirInherit };
0197     enum TextMode { ModeAppend, ModeReplace, ModeInherit };
0198     enum TextPlace { PlaceStart, PlaceCenter, PlaceEnd, PlaceInherit };
0199     enum TextWrap { Wrap, NoWrap, WrapInherit };
0200     enum TextWriting { WritingLrTb, WritingRlTb, WritingTbLr, WritingTbRl };
0201 
0202     void init ();
0203     bool parseParam (const TrieString &name, const QString &value);
0204     void mask (const SmilTextProperties &props);
0205 
0206     QString font_family;
0207     QString text_style;
0208     int font_color;
0209     int background_color;
0210     unsigned char text_direction;
0211     unsigned char font_style;
0212     unsigned char font_weight;
0213     unsigned char text_mode;
0214     unsigned char text_place;
0215     unsigned char text_wrap;
0216     unsigned char space;
0217     unsigned char text_writing;
0218     unsigned char text_align;
0219     unsigned char padding;
0220     SizeType font_size;
0221 };
0222 
0223 class SmilColorProperty
0224 {
0225 public:
0226     void init ();
0227     void setColor (const QString &value);
0228     void setOpacity (const QString &value);
0229 
0230     unsigned int color;
0231     int opacity;
0232 };
0233 
0234 class MediaOpacity
0235 {
0236 public:
0237     void init ();
0238 
0239     unsigned short opacity;
0240     unsigned short bg_opacity;
0241 };
0242 
0243 class TransitionModule
0244 {
0245 public:
0246     TransitionModule ()
0247      : trans_start_time (0),
0248        trans_out_timer (nullptr),
0249        trans_out_active (false) {}
0250 
0251     void init ();
0252     void begin (Node *n, Runtime *r);
0253     bool handleMessage (Node *n, Runtime *r, Surface *s, MessageType m, void *);
0254     void cancelTimer (Node *n);
0255     void finish (Node *n);
0256 
0257     NodePtrW trans_in;
0258     NodePtrW trans_out;
0259     NodePtrW active_trans;
0260     unsigned int trans_start_time;
0261     unsigned int trans_end_time;
0262     Posting *trans_out_timer;
0263     float trans_gain;
0264     ConnectionList m_TransformedIn;        // transIn ready
0265     ConnectionLink transition_updater;
0266     bool trans_out_active;
0267 };
0268 
0269 //-----------------------------------------------------------------------------
0270 
0271 namespace SMIL {
0272 
0273 const short id_node_smil = 100;
0274 const short id_node_head = 101;
0275 const short id_node_state = 102;
0276 const short id_node_layout = 103;
0277 const short id_node_root_layout = 104;
0278 const short id_node_region = 105;
0279 const short id_node_regpoint = 106;
0280 const short id_node_transition = 107;
0281 const short id_node_body = 110;
0282 const short id_node_par = 111;
0283 const short id_node_seq = 112;
0284 const short id_node_switch = 113;
0285 const short id_node_excl = 114;
0286 const short id_node_text = 120;
0287 const short id_node_ref = 121;
0288 const short id_node_brush = 122;
0289 const short id_node_smil_text = 123;
0290 const short id_node_tev = 124;
0291 const short id_node_clear = 125;
0292 const short id_node_text_styling = 126;
0293 const short id_node_set_value = 127;
0294 const short id_node_new_value = 128;
0295 const short id_node_del_value = 129;
0296 const short id_node_send = 130;
0297 const short id_node_set = 132;
0298 const short id_node_animate = 133;
0299 const short id_node_animate_color = 134;
0300 const short id_node_animate_motion = 135;
0301 const short id_node_title = 140;
0302 const short id_node_param = 141;
0303 const short id_node_meta = 142;
0304 const short id_node_priorityclass = 143;
0305 const short id_node_div = 144;
0306 const short id_node_span = 145;
0307 const short id_node_p = 146;
0308 const short id_node_br = 147;
0309 const short id_node_anchor = 150;
0310 const short id_node_area = 151;
0311 const short id_node_state_data = 151;
0312 const short id_node_first = id_node_smil;
0313 const short id_node_first_timed_mrl = id_node_body;
0314 const short id_node_last_timed_mrl = id_node_animate_motion;
0315 const short id_node_first_mediatype = id_node_text;
0316 const short id_node_last_mediatype = id_node_brush;
0317 const short id_node_first_group = id_node_body;
0318 const short id_node_last_group = id_node_excl;
0319 const short id_node_last = 200; // reserve 100 ids
0320 
0321 /**
0322  * '<smil>' tag
0323  */
0324 class Smil : public Mrl {
0325 public:
0326     Smil (NodePtr & d) : Mrl (d, id_node_smil) {}
0327     Node *childFromTag (const QString & tag) override;
0328     const char * nodeName () const override { return "smil"; }
0329     PlayType playType () override { return play_type_video; }
0330     void activate () override;
0331     void deactivate () override;
0332     void closed () override;
0333     void *role (RoleType msg, void *content=nullptr) override;
0334     void message (MessageType msg, void *content=nullptr) override;
0335     void accept (Visitor *v) override { v->visit (this); }
0336     void jump (const QString & id);
0337     static Smil * findSmilNode (Node * node);
0338 
0339     NodePtrW layout_node;
0340     NodePtrW state_node;
0341 };
0342 
0343 /**
0344  * Represents optional 'head' tag of SMIL document as in
0345  * &lt;smil&gt;&lt;head/&gt;&lt;body/&gt;&lt;/smil&gt;
0346  */
0347 class Head : public Element
0348 {
0349 public:
0350     Head (NodePtr & d) : Element (d, id_node_head) {}
0351     Node *childFromTag (const QString & tag) override;
0352     const char * nodeName () const override { return "head"; }
0353     void closed () override;
0354     void message (MessageType msg, void *content=nullptr) override;
0355 };
0356 
0357 /**
0358  * Defines state, should reside below 'head' element
0359  */
0360 class State : public Element
0361 {
0362 public:
0363     enum Where { before, after, child };
0364     enum Method { get, put };
0365     enum Replace { all, instance, none };
0366 
0367     State (NodePtr & d);
0368 
0369     Node *childFromTag (const QString & tag) override;
0370     void closed () override;
0371     void activate () override;
0372     void parseParam (const TrieString & name, const QString & value) override;
0373     void deactivate () override;
0374     void message (MessageType msg, void *content=nullptr) override;
0375     void *role (RoleType msg, void *content=nullptr) override;
0376     const char * nodeName () const override { return "state"; }
0377 
0378     QString domain ();
0379     void newValue (Node *ref, Where w, const QString &name, const QString &val);
0380     void setValue (Node *ref, const QString &value);
0381     void delValue (Node *ref);
0382     void stateChanged (Node *ref);
0383 
0384     ConnectionList m_StateChangeListeners;        // setValue changed a value
0385     PostponePtr postpone_lock;                    // pause while loading src
0386     MediaInfo *media_info;
0387     QString m_url;
0388 };
0389 
0390 /**
0391  * Defines region layout, should reside below 'head' element
0392  */
0393 class Layout : public Element
0394 {
0395 public:
0396     Layout (NodePtr & d);
0397     Node *childFromTag (const QString & tag) override;
0398     const char * nodeName () const override { return "layout"; }
0399     void closed () override;
0400     void message (MessageType msg, void *content=nullptr) override;
0401     void accept (Visitor *v) override { v->visit (this); }
0402 
0403     NodePtrW root_layout;
0404 };
0405 
0406 /**
0407  * Base class for SMIL::Region, SMIL::RootLayout and SMIL::Layout
0408  */
0409 class RegionBase : public Element
0410 {
0411 public:
0412     enum ShowBackground { ShowAlways, ShowWhenActive };
0413 
0414     ~RegionBase () override;
0415     void activate () override;
0416     void deactivate () override;
0417     void parseParam (const TrieString & name, const QString & value) override;
0418     void message (MessageType msg, void *content=nullptr) override;
0419     void *role (RoleType msg, void *content=nullptr) override;
0420     void accept (Visitor *v) override { v->visit (this); }
0421     /**
0422      * repaints region, calls scheduleRepaint(x,y,w,h) on view
0423      */
0424     void repaint ();
0425     void repaint (const SRect & rect);
0426 
0427     SurfacePtrW region_surface;
0428     MediaInfo *media_info;
0429     CalculatedSizer sizes;
0430 
0431     int z_order;
0432     SmilColorProperty background_color;
0433     MediaOpacity media_opacity;
0434     QString background_image;
0435     enum BackgroundRepeat {
0436         BgRepeat, BgRepeatX, BgRepeatY, BgNoRepeat, BgInherit
0437     } bg_repeat;
0438     ShowBackground show_background;
0439     Fit fit;
0440     SmilTextProperties font_props;
0441     ConnectionList m_AttachedMediaTypes;   // active attached mediatypes
0442 protected:
0443     RegionBase (NodePtr & d, short id);
0444     PostponePtr postpone_lock;               // pause while loading bg image
0445     void dataArrived (); // image downloaded
0446 };
0447 
0448 /**
0449  * Represents the root area for the other regions
0450  */
0451 class RootLayout : public RegionBase
0452 {
0453 public:
0454     RootLayout (NodePtr & d)
0455         : RegionBase (d, id_node_root_layout) {}
0456     ~RootLayout () override;
0457     void closed () override;
0458     void deactivate () override;
0459     void message (MessageType msg, void *content=nullptr) override;
0460     void *role (RoleType msg, void *content=nullptr) override;
0461     const char * nodeName () const override { return "root-layout"; }
0462 };
0463 
0464 /**
0465  * Represents a rectangle on the viewing area
0466  */
0467 class Region : public RegionBase
0468 {
0469 public:
0470     Region (NodePtr & d);
0471     ~Region () override;
0472     void deactivate () override;
0473     const char * nodeName () const override { return "region"; }
0474     Node *childFromTag (const QString & tag) override;
0475     void message (MessageType msg, void *content=nullptr) override;
0476     void *role (RoleType msg, void *content=nullptr) override;
0477 private:
0478     MouseListeners mouse_listeners;
0479 };
0480 
0481 /**
0482  * Represents a regPoint element for alignment inside regions
0483  */
0484 class RegPoint : public Element
0485 {
0486 public:
0487     RegPoint (NodePtr & d) : Element(d, id_node_regpoint) {}
0488     ~RegPoint () override {}
0489     const char * nodeName () const override { return "regPoint"; }
0490     void parseParam (const TrieString & name, const QString & value) override;
0491     CalculatedSizer sizes;
0492 };
0493 
0494 /**
0495  * Represents a transition element for starting media types
0496  */
0497 class Transition : public Element
0498 {
0499 public:
0500     enum TransType {
0501         TransTypeNone = 0,
0502         BarWipe, IrisWipe, ClockWipe, SnakeWipe, // required, TODO
0503         BoxWipe, FourBoxWipe, BarnDoorWipe, DiagonalWipe, BowTieWipe,
0504         MiscDiagonalWipe, VeeWipe, BarnVeeWipe, ZigZagWipe, BarnZigZagWipe,
0505         TriangleWipe, ArrowHeadWipe, PentagonWipe, HexagonWipe, EllipseWipe,
0506         EyeWipe, RoundRectWipe, StarWipe, MiscShapeWipe,
0507         PinWheelWipe, SingleSweepWipe, FanWipe, DoubleFanWipe,
0508         DoubleSweepWipe, SaloonDoorWipe, WindShieldWipe,
0509         SpiralWipe, ParallelSnakesWipe, BoxSnakesWipe, WaterFallWipe,
0510         PushWipe, SideWipe, Fade,
0511         TransLast
0512     };
0513     enum TransSubType {
0514         SubTransTypeNone = 0,
0515         SubLeftToRight, SubTopToBottom, SubTopLeft, SubTopRight,
0516         SubBottomRight, SubBottomLeft,
0517         SubTopCenter, SubRightCenter, SubBottomCenter, SubLeftCenter,
0518         SubCornersIn, SubCornersOut,
0519         SubCircle, SubVertical, SubHorizontal,
0520         SubFromLeft, SubFromTop, SubFromRight, SubFromBottom,
0521         SubCrossfade, SubFadeToColor, SubFadeFromColor,
0522         SubRectangle, SubDiamond,
0523         SubClockwiseTwelve, SubClockwiseThree, SubClockwiseSix,
0524         SubClockwiseNine,
0525          // and lots more .. TODO
0526         SubTransLast
0527     };
0528     Transition (NodePtr & d);
0529     ~Transition () override {}
0530     void activate () override;
0531     void accept (Visitor * v) override { v->visit (this); }
0532     const char * nodeName () const override { return "transition"; }
0533     void parseParam (const TrieString & name, const QString & value) override;
0534     bool supported ();
0535     TransType type;
0536     TransSubType sub_type;
0537     TransTypeInfo *type_info;
0538     enum { dir_forward, dir_reverse } direction;
0539     int dur; // centi seconds
0540     float start_progress, end_progress;
0541     unsigned int fade_color;
0542 };
0543 
0544 /**
0545  * Abstract base for the group elements (par/seq/excl/..)
0546  */
0547 class GroupBase : public Element
0548 {
0549 public:
0550     ~GroupBase () override;
0551     Node *childFromTag (const QString & tag) override;
0552     PlayType playType () override { return play_type_none; }
0553     void parseParam (const TrieString &name, const QString &value) override;
0554     void init () override;
0555     void finish () override;
0556     void activate () override;
0557     void deactivate () override;
0558     void reset () override;
0559     void message (MessageType msg, void *content=nullptr) override;
0560     void *role (RoleType msg, void *content=nullptr) override;
0561     void setJumpNode (NodePtr);
0562     Runtime *runtime;
0563 protected:
0564     GroupBase (NodePtr & d, short id);
0565     NodePtrW jump_node;
0566 };
0567 
0568 /**
0569  * A Par represents parallel processing of all its children
0570  */
0571 class Par : public GroupBase
0572 {
0573 public:
0574     Par (NodePtr & d) : GroupBase (d, id_node_par) {}
0575     const char * nodeName () const override { return "par"; }
0576     void begin () override;
0577     void reset () override;
0578     void message (MessageType msg, void *content=nullptr) override;
0579     void *role (RoleType msg, void *content=nullptr) override;
0580     void accept (Visitor * v) override { v->visit (this); }
0581 };
0582 
0583 /**
0584  * A Seq represents sequential processing of all its children
0585  */
0586 class Seq : public GroupBase
0587 {
0588 public:
0589     Seq (NodePtr & d) : GroupBase(d, id_node_seq) {}
0590     const char * nodeName () const override { return "seq"; }
0591     void begin () override;
0592     void message (MessageType msg, void *content=nullptr) override;
0593     void *role (RoleType msg, void *content=nullptr) override;
0594     void accept (Visitor * v) override { v->visit (this); }
0595     ConnectionLink starting_connection;
0596     ConnectionLink trans_connection;
0597 protected:
0598     Seq (NodePtr & d, short id) : GroupBase(d, id) {}
0599 };
0600 
0601 /**
0602  * Represents the 'body' tag of SMIL document as in
0603  * &lt;smil&gt;&lt;head/&gt;&lt;body/&gt;&lt;/smil&gt;
0604  */
0605 class Body : public Seq
0606 {
0607 public:
0608     Body (NodePtr & d) : Seq (d, id_node_body) {}
0609     const char * nodeName () const override { return "body"; }
0610 };
0611 
0612 /**
0613  * An Excl represents exclusive processing of one of its children
0614  */
0615 class Excl : public GroupBase
0616 {
0617 public:
0618     Excl (NodePtr & d);
0619     ~Excl () override;
0620     const char * nodeName () const override { return "excl"; }
0621     Node *childFromTag (const QString & tag) override;
0622     void begin () override;
0623     void deactivate () override;
0624     void message (MessageType msg, void *content=nullptr) override;
0625     void accept (Visitor * v) override { v->visit (this); }
0626 
0627     struct ConnectionItem {
0628         ConnectionItem (ConnectionItem *n) : next (n) {}
0629         ConnectionLink link;
0630         ConnectionItem *next;
0631     } *started_event_list;
0632     ConnectionLink stopped_connection;
0633     NodeRefList priority_queue;
0634     NodePtrW cur_node;
0635 };
0636 
0637 /**
0638  * A PriorityClass groups children within an Excl element
0639  */
0640 class PriorityClass : public Element
0641 {
0642 public:
0643     PriorityClass (NodePtr &d)
0644         : Element (d, id_node_priorityclass) {}
0645     const char * nodeName () const override { return "priorityClass"; }
0646     Node *childFromTag (const QString & tag) override;
0647     void init () override;
0648     void parseParam (const TrieString &, const QString &) override;
0649     void message (MessageType msg, void *content=nullptr) override;
0650     void accept (Visitor * v) override { v->visit (this); }
0651 
0652     enum { PeersStop, PeersPause, PeersDefer, PeersNever } peers;
0653     enum { HigherStop, HigherPause } higher;
0654     enum { LowerDefer, LowerNever } lower;
0655     enum { PauseDisplayDisable, PauseDisplayHide, PauseDisplayShow } pause_display;
0656 };
0657 
0658 /*
0659  * An automatic selection between child elements based on a condition
0660  */
0661 class Switch : public GroupBase
0662 {
0663 public:
0664     Switch (NodePtr &d) : GroupBase (d, id_node_switch) {}
0665     const char * nodeName () const override { return "switch"; }
0666     // Condition
0667     void begin () override;
0668     void init () override;
0669     void deactivate () override;
0670     void reset () override;
0671     void message (MessageType msg, void *content=nullptr) override;
0672     void accept (Visitor * v) override { v->visit (this); }
0673 
0674     Node *chosenOne ();
0675 private:
0676     NodePtrW chosen_one;
0677 };
0678 
0679 class LinkingBase : public Element
0680 {
0681 public:
0682     ~LinkingBase () override {}
0683     void deactivate () override;
0684     void parseParam (const TrieString & name, const QString & value) override;
0685     ConnectionLink mediatype_attach;
0686     QString href;
0687     QString target;
0688     enum { show_new, show_replace } show;
0689 protected:
0690     LinkingBase (NodePtr & d, short id);
0691 };
0692 
0693 class Anchor : public LinkingBase
0694 {
0695 public:
0696     Anchor (NodePtr & d);
0697     ~Anchor () override {}
0698     void activate () override;
0699     void message (MessageType msg, void *content=nullptr) override;
0700     void *role (RoleType msg, void *content=nullptr) override;
0701     const char * nodeName () const override { return "a"; }
0702     Node *childFromTag (const QString & tag) override;
0703     void accept (Visitor * v) override { v->visit (this); }
0704 };
0705 
0706 class Area : public LinkingBase
0707 {
0708 public:
0709     Area (NodePtr & d, const QString & tag);
0710     ~Area () override;
0711     void activate () override;
0712     const char * nodeName () const override { return tag.constData (); }
0713     void accept (Visitor * v) override { v->visit (this); }
0714     void parseParam (const TrieString & name, const QString & value) override;
0715     void *role (RoleType msg, void *content=nullptr) override;
0716     SizeType * coords;
0717     int nr_coords;
0718     const QByteArray tag;
0719     MouseListeners mouse_listeners;
0720 };
0721 
0722 /**
0723  * Abstract base for the MediaType classes (video/audio/text/img/..)
0724  */
0725 class MediaType : public Mrl
0726 {
0727 public:
0728     MediaType (NodePtr & d, const QByteArray& t, short id);
0729     ~MediaType () override;
0730 
0731     Node *childFromTag (const QString & tag) override;
0732     const char * nodeName () const override { return m_type.constData (); }
0733     void closed () override;
0734     void init () override;
0735     void activate () override;
0736     void deactivate () override;
0737     void defer () override;
0738     void undefer () override;
0739     void begin () override;
0740     void finish () override;
0741     void reset () override;
0742     SRect calculateBounds ();
0743     void parseParam (const TrieString & name, const QString & value) override;
0744     void message (MessageType msg, void *content=nullptr) override;
0745     void *role (RoleType msg, void *content=nullptr) override;
0746     void accept (Visitor *v) override { v->visit (this); }
0747 
0748     Surface *surface ();
0749 
0750     Runtime *runtime;
0751     SurfacePtrW sub_surface;
0752     NodePtrW external_tree; // if src points to playlist, the resolved top node
0753     TransitionModule transition;
0754     NodePtrW region_node;
0755     QByteArray m_type;
0756     CalculatedSizer sizes;
0757     CalculatedSizer *pan_zoom;
0758     Fit fit;
0759     Fit effective_fit;
0760     SmilColorProperty background_color;
0761     MediaOpacity media_opacity;
0762     unsigned int bitrate;
0763     enum { sens_opaque, sens_transparent, sens_percentage } sensitivity;
0764 
0765 protected:
0766     virtual void prefetch ();
0767     virtual void clipStart ();
0768     virtual void clipStop ();
0769 
0770     MouseListeners mouse_listeners;
0771     ConnectionList m_MediaAttached;
0772     ConnectionLink region_attach;          // attached to region
0773     ConnectionLink document_postponed;     // pause audio/video accordantly
0774     PostponePtr postpone_lock;
0775 };
0776 
0777 class RefMediaType : public MediaType
0778 {
0779 public:
0780     RefMediaType (NodePtr &doc, const QByteArray &tag);
0781     Node *childFromTag (const QString & tag) override;
0782     void activate () override;
0783     void begin () override;
0784     void finish () override;
0785     PlayType playType () override;
0786     void accept (Visitor *) override;
0787     void message (MessageType msg, void *content=nullptr) override;
0788     void *role (RoleType msg, void *content=nullptr) override;
0789     void prefetch () override;
0790     void clipStart () override;
0791 };
0792 
0793 class TextMediaType : public MediaType
0794 {
0795 public:
0796     TextMediaType (NodePtr & d);
0797     PlayType playType () override { return play_type_info; }
0798     void init () override;
0799     void accept (Visitor *) override;
0800     void parseParam (const TrieString &, const QString &) override;
0801     void prefetch () override;
0802 
0803     QString font_name;
0804     int font_size;
0805     unsigned int font_color;
0806     enum { align_left, align_center, align_right } halign;
0807 };
0808 
0809 class Brush : public MediaType
0810 {
0811 public:
0812     Brush (NodePtr & d);
0813     void init () override;
0814     void accept (Visitor *) override;
0815     void parseParam (const TrieString &, const QString &) override;
0816     SmilColorProperty color;
0817 };
0818 
0819 class SmilText : public Element
0820 {
0821 public:
0822     SmilText (NodePtr &doc);
0823     ~SmilText () override;
0824     void init () override;
0825     void activate () override;
0826     void begin () override;
0827     void finish () override;
0828     void deactivate () override;
0829     void reset () override;
0830     const char *nodeName () const override { return "smilText"; }
0831     Node *childFromTag (const QString & tag) override;
0832     void parseParam (const TrieString &name, const QString &value) override;
0833     void message (MessageType msg, void *content=nullptr) override;
0834     void *role (RoleType msg, void *content=nullptr) override;
0835     void accept (Visitor *v) override { v->visit (this); }
0836 
0837     Surface *surface ();
0838     void updateBounds (bool remove);
0839 
0840     SmilColorProperty background_color;
0841     MediaOpacity media_opacity;
0842     TransitionModule transition;
0843     SmilTextProperties props;
0844     SurfacePtrW text_surface;
0845     NodePtrW region_node;
0846     CalculatedSizer sizes;
0847     SSize size;
0848     ConnectionLink region_attach;
0849     ConnectionList media_attached;
0850     MouseListeners mouse_listeners;
0851     Runtime *runtime;
0852 };
0853 
0854 class TextFlow : public Element
0855 {
0856 public:
0857     TextFlow (NodePtr &doc, short id, const QByteArray &tag);
0858     ~TextFlow () override;
0859 
0860     void init () override;
0861     void activate () override;
0862     const char *nodeName () const override { return tag.data (); }
0863     Node *childFromTag (const QString &tag) override;
0864     void parseParam (const TrieString &name, const QString &value) override;
0865     void accept (Visitor *v) override { v->visit (this); }
0866 
0867     SmilTextProperties props;
0868     QByteArray tag;
0869 };
0870 
0871 class TemporalMoment : public Element
0872 {
0873 public:
0874     TemporalMoment (NodePtr &doc, short id, const QByteArray &tag);
0875     ~TemporalMoment () override;
0876     void init () override;
0877     void activate () override;
0878     void begin () override;
0879     void deactivate () override;
0880     const char *nodeName () const override { return tag.data (); }
0881     Node *childFromTag (const QString & tag) override;
0882     void parseParam (const TrieString &name, const QString &value) override;
0883     void message (MessageType msg, void *content=nullptr) override;
0884     void *role (RoleType msg, void *content=nullptr) override;
0885     void accept (Visitor *v) override { v->visit (this); }
0886 
0887     Runtime *runtime;
0888     QByteArray tag;
0889 };
0890 
0891 class StateValue : public Element
0892 {
0893 public:
0894     ~StateValue () override;
0895 
0896     void init () override;
0897     void activate () override;
0898     void finish () override;
0899     void deactivate () override;
0900     void reset () override;
0901     void parseParam (const TrieString &name, const QString &value) override;
0902     void message (MessageType msg, void *content=nullptr) override;
0903     void *role (RoleType msg, void *content=nullptr) override;
0904 protected:
0905     StateValue (NodePtr &d, short _id);
0906 
0907     QString value;
0908     NodePtrW state;
0909     Expression *ref;
0910     Runtime *runtime;
0911 };
0912 
0913 class NewValue : public StateValue
0914 {
0915 public:
0916     NewValue (NodePtr &d) : StateValue (d, id_node_new_value) {}
0917 
0918     void init () override;
0919     void begin () override;
0920     void parseParam (const TrieString &name, const QString &value) override;
0921     const char *nodeName () const override { return "newvalue"; }
0922 
0923 private:
0924     QString name;
0925     SMIL::State::Where where;
0926 };
0927 
0928 class SetValue : public StateValue
0929 {
0930 public:
0931     SetValue (NodePtr &d) : StateValue (d, id_node_set_value) {}
0932 
0933     void begin () override;
0934     const char *nodeName () const override { return "setvalue"; }
0935 };
0936 
0937 class DelValue : public StateValue
0938 {
0939 public:
0940     DelValue (NodePtr &d) : StateValue (d, id_node_del_value) {}
0941 
0942     void begin () override;
0943     const char *nodeName () const override { return "delvalue"; }
0944 };
0945 
0946 class Send : public StateValue
0947 {
0948 public:
0949     Send (NodePtr &d) : StateValue (d, id_node_send), media_info (nullptr) {}
0950 
0951     void init () override;
0952     void begin () override;
0953     void deactivate () override;
0954     void parseParam (const TrieString &name, const QString &value) override;
0955     void message (MessageType msg, void *content=nullptr) override;
0956     const char *nodeName () const override { return "send"; }
0957 
0958 private:
0959     QString action;
0960     SMIL::State::Replace replace;
0961     SMIL::State::Method method;
0962     MediaInfo *media_info;
0963 };
0964 
0965 class AnimateGroup : public Element
0966 {
0967 public:
0968     ~AnimateGroup () override;
0969     void init () override;
0970     void activate () override;
0971     void finish () override;
0972     void deactivate () override;
0973     void reset () override;
0974     void parseParam (const TrieString & name, const QString & value) override;
0975     void message (MessageType msg, void *content=nullptr) override;
0976     void *role (RoleType msg, void *content=nullptr) override;
0977     Runtime *runtime;
0978 protected:
0979     virtual void restoreModification ();
0980     Node *targetElement ();
0981     AnimateGroup (NodePtr &d, short _id);
0982     NodePtrW target_element;
0983     TrieString changed_attribute;
0984     QString target_id;
0985     QString change_to;
0986     int modification_id;
0987 };
0988 
0989 class Set : public AnimateGroup
0990 {
0991 public:
0992     Set (NodePtr & d) : AnimateGroup (d, id_node_set) {}
0993     void begin () override;
0994     const char * nodeName () const override { return "set"; }
0995     PlayType playType () override { return play_type_none; }
0996 };
0997 
0998 class AnimateBase : public AnimateGroup
0999 {
1000 public:
1001     struct Point2D {
1002         float x;
1003         float y;
1004     };
1005     AnimateBase (NodePtr &d, short id);
1006     ~AnimateBase () override;
1007 
1008     void init () override;
1009     void begin () override;
1010     void finish () override;
1011     void deactivate () override;
1012     void parseParam (const TrieString & name, const QString & value) override;
1013     void message (MessageType msg, void *content=nullptr) override;
1014     void accept (Visitor *v) override { v->visit (this); }
1015     PlayType playType () override { return play_type_none; }
1016 
1017     Posting *anim_timer;
1018 protected:
1019     virtual bool timerTick (unsigned int cur_time) = 0;
1020     virtual void applyStep () = 0;
1021 
1022     bool setInterval ();
1023 
1024     enum { acc_none, acc_sum } accumulate;
1025     enum { add_replace, add_sum } additive;
1026     enum { calc_discrete, calc_linear, calc_paced, calc_spline } calcMode;
1027     QString change_from;
1028     QString change_by;
1029     QStringList values;
1030     ConnectionLink change_updater;
1031     float *keytimes;
1032     Point2D *spline_table;
1033     QStringList splines;
1034     float control_point[4];
1035     unsigned int keytime_count;
1036     unsigned int keytime_steps;
1037     unsigned int interval;
1038     unsigned int interval_start_time;
1039     unsigned int interval_end_time;
1040 };
1041 
1042 class Animate : public AnimateBase
1043 {
1044 public:
1045     Animate (NodePtr &doc);
1046 
1047     void init () override;
1048     void begin () override;
1049     void finish () override;
1050     void deactivate () override;
1051     //virtual void accept (Visitor *v) { v->visit (this); }
1052     const char * nodeName () const override { return "animate"; }
1053 
1054 private:
1055     bool timerTick (unsigned int cur_time) override;
1056     void applyStep () override;
1057 
1058     void cleanUp ();
1059 
1060     int num_count;
1061     SizeType *begin_;
1062     SizeType *cur;
1063     SizeType *delta;
1064     SizeType *end;
1065 };
1066 
1067 class AnimateMotion : public AnimateBase
1068 {
1069 public:
1070     AnimateMotion (NodePtr &d) : AnimateBase (d, id_node_animate_motion) {}
1071 
1072     void init () override;
1073     void begin () override;
1074     void finish () override;
1075     //virtual void accept (Visitor *v) { v->visit (this); }
1076     const char * nodeName () const override { return "animateMotion"; }
1077 
1078 private:
1079     void restoreModification () override;
1080     bool timerTick (unsigned int cur_time) override;
1081     void applyStep () override;
1082 
1083     CalculatedSizer old_sizes;
1084     SizeType begin_x, begin_y;
1085     SizeType cur_x, cur_y;
1086     SizeType delta_x, delta_y;
1087     SizeType end_x, end_y;
1088 };
1089 
1090 class AnimateColor : public AnimateBase
1091 {
1092 public:
1093     struct Channels {
1094         short blue;
1095         short green;
1096         short red;
1097         short alpha;
1098         unsigned int argb ();
1099         void clear ();
1100         Channels &operator *= (const float f);
1101         Channels &operator += (const Channels &c);
1102         Channels &operator -= (const Channels &c);
1103     };
1104 
1105     AnimateColor (NodePtr &d) : AnimateBase (d, id_node_animate_color) {}
1106 
1107     void init () override;
1108     void begin () override;
1109     void finish () override;
1110     //virtual void accept (Visitor *v) { v->visit (this); }
1111     const char * nodeName () const override { return "animateColor"; }
1112 
1113 private:
1114     bool timerTick (unsigned int cur_time) override;
1115     void applyStep () override;
1116 
1117     Channels begin_c;
1118     Channels cur_c;
1119     Channels delta_c;
1120     Channels end_c;
1121 };
1122 
1123 // TODO transitionFilter
1124 
1125 class Param : public Element
1126 {
1127 public:
1128     Param (NodePtr & d) : Element (d, id_node_param) {}
1129     const char * nodeName () const override { return "param"; }
1130     void activate () override;
1131 };
1132 
1133 } // SMIL namespace
1134 
1135 }  // KMPlayer namespace
1136 
1137 #endif //_KMPLAYER_SMIL_H_