2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
25 #include "Rasterizer.h"
26 #include "../SubPic/SubPicProviderImpl.h"
27 #include "../SubPic/ISimpleSubPic.h"
29 #include <boost/flyweight/key_value.hpp>
30 #include <boost/smart_ptr.hpp>
31 #include "mru_cache.h"
33 #define RTS_POS_SEGMENT_INDEX_BITS 16
34 #define RTS_POS_SUB_INDEX_MASK ((1<<RTS_POS_SEGMENT_INDEX_BITS)-1)
36 class CMyFont
: public CFont
39 int m_ascent
, m_descent
;
41 CMyFont(const STSStyleBase
& style
);
44 typedef ::boost::flyweights::flyweight
<::boost::flyweights::key_value
<STSStyleBase
, CMyFont
>, ::boost::flyweights::no_locking
> FwCMyFont
;
49 typedef ::boost::shared_ptr
<CClipper
> SharedPtrCClipper
;
51 struct CompositeDrawItem
;
52 typedef CAtlList
<CompositeDrawItem
> CompositeDrawItemList
;
53 typedef CAtlList
<CompositeDrawItemList
> CompositeDrawItemListList
;
56 typedef CWord
* PCWord
;
57 typedef ::boost::shared_ptr
<CWord
> SharedPtrCWord
;
58 typedef ::boost::shared_ptr
<CPolygon
> SharedPtrCPolygon
;
60 class CClipperPaintMachine
;
61 typedef ::boost::shared_ptr
<CClipperPaintMachine
> SharedPtrCClipperPaintMachine
;
64 interface IXySubRenderFrame
;
69 void Transform(PathData
* path_data
, const CPointCoor2
& org
);
71 void Transform_C(PathData
* path_data
, const CPointCoor2
&org
);
72 void Transform_SSE2(PathData
* path_data
, const CPointCoor2
&org
);
73 bool CreateOpaqueBox();
76 virtual bool CreatePath(PathData
* path_data
) = 0;
78 bool DoPaint(const CPointCoor2
& p
, const CPointCoor2
& trans_org
, SharedPtrOverlay
* overlay
, const OverlayKey
& key
);
80 // str[0] = 0 -> m_fLineBreak = true (in this case we only need and use the height of m_font from the whole class)
81 CWord(const FwSTSStyle
& style
, const CStringW
& str
, int ktype
, int kstart
, int kend
82 , double target_scale_x
=1.0, double target_scale_y
=1.0
83 , bool round_to_whole_pixel_after_scale_to_target
= false);
87 virtual SharedPtrCWord
Copy() = 0;
88 virtual bool Append(const SharedPtrCWord
& w
);
90 bool operator==(const CWord
& rhs
)const;
92 static void PaintFromOverlay(const CPointCoor2
& p
, const CPointCoor2
& trans_org2
, OverlayKey
&subpixel_variance_key
, SharedPtrOverlay
& overlay
);
93 void PaintFromNoneBluredOverlay(SharedPtrOverlay raterize_result
, const OverlayKey
& overlay_key
, SharedPtrOverlay
* overlay
);
94 bool PaintFromScanLineData2(const CPointCoor2
& psub
, const ScanLineData2
& scan_line_data2
, const OverlayKey
& key
, SharedPtrOverlay
* overlay
);
95 bool PaintFromPathData(const CPointCoor2
& psub
, const CPointCoor2
& trans_org
, const PathData
& path_data
, const OverlayKey
& key
, SharedPtrOverlay
* overlay
);
96 bool PaintFromRawData( const CPointCoor2
& psub
, const CPointCoor2
& trans_org
, const OverlayKey
& key
, SharedPtrOverlay
* overlay
);
101 bool m_fWhiteSpaceChar
, m_fLineBreak
;
105 SharedPtrCPolygon m_pOpaqueBox
;
107 int m_ktype
, m_kstart
, m_kend
;
109 int m_width
, m_ascent
, m_descent
;
111 double m_target_scale_x
, m_target_scale_y
;
112 bool m_round_to_whole_pixel_after_scale_to_target
;//it is necessary to avoid some artifacts
114 //friend class CWordCache;
115 friend class PathDataCacheKey
;
116 friend class ClipperTraits
;
117 friend class ClipperAlphaMaskCacheKey
;
118 friend class CWordPaintMachine
;
119 friend class CWordPaintResultKey
;
120 friend class CClipper
;
123 class CText
: public CWord
128 int m_width
, m_ascent
, m_descent
;
130 typedef ::boost::shared_ptr
<TextInfo
> SharedPtrTextInfo
;
132 virtual bool CreatePath(PathData
* path_data
);
134 static void GetTextInfo(TextInfo
*output
, const FwSTSStyle
& style
, const CStringW
& str
);
136 CText(const FwSTSStyle
& style
, const CStringW
& str
, int ktype
, int kstart
, int kend
137 , double target_scale_x
=1.0, double target_scale_y
=1.0);
138 CText(const CText
& src
);
140 virtual SharedPtrCWord
Copy();
141 virtual bool Append(const SharedPtrCWord
& w
);
144 class CPolygon
: public CWord
146 bool Get6BitFixedPoint(CStringW
& str
, LONG
& ret
);
147 bool GetPOINT(CStringW
& str
, POINT
& ret
);
151 double m_scalex
, m_scaley
;
154 CAtlArray
<BYTE
> m_pathTypesOrg
;
155 CAtlArray
<CPoint
> m_pathPointsOrg
;
157 virtual bool CreatePath(PathData
* path_data
);
160 CPolygon(const FwSTSStyle
& style
, const CStringW
& str
, int ktype
, int kstart
, int kend
161 , double scalex
, double scaley
, int baseline
162 , double target_scale_x
=1.0, double target_scale_y
=1.0
163 , bool round_to_whole_pixel_after_scale_to_target
= false);
164 // can't use a const reference because we need to use CAtlArray::Copy which expects a non-const reference
168 virtual SharedPtrCWord
Copy();
169 virtual bool Append(const SharedPtrCWord
& w
);
171 friend class ClipperTraits
;
172 friend class ClipperAlphaMaskCacheKey
;
173 friend class PathDataCacheKey
;
178 EF_MOVE
= 0, // {\move(x1=param[0], y1=param[1], x2=param[2], y2=param[3], t1=t[0], t2=t[1])} or {\pos(x=param[0], y=param[1])}
179 EF_ORG
, // {\org(x=param[0], y=param[1])}
180 EF_FADE
, // {\fade(a1=param[0], a2=param[1], a3=param[2], t1=t[0], t2=t[1], t3=t[2], t4=t[3])} or {\fad(t1=t[1], t2=t[2])
181 EF_BANNER
, // Banner;delay=param[0][;lefttoright=param[1];fadeawaywidth=param[2]]
182 EF_SCROLL
, // Scroll up/down=param[3];top=param[0];bottom=param[1];delay=param[2][;fadeawayheight=param[4]]
185 #define EF_NUMBEROFEFFECTS 5
192 memset(param
, 0, sizeof(param
));
193 memset(t
, 0, sizeof(t
));
195 bool operator==(const Effect
& rhs
)const
197 return type
==rhs
.type
198 && !memcmp(param
, rhs
.param
, sizeof(param
))
199 && !memcmp(t
, rhs
.t
, sizeof(t
));
210 SharedPtrCPolygon m_polygon
;
220 GrayImage2
* PaintSimpleClipper();
221 GrayImage2
* PaintBaseClipper();
222 GrayImage2
* PaintBannerClipper();
223 GrayImage2
* PaintScrollClipper();
227 CClipper(CStringW str
, CSizeCoor2 size
, double scalex
, double scaley
, bool inverse
228 , double target_scale_x
=1.0, double target_scale_y
=1.0);
229 void SetEffect(const Effect
& effect
, int effectType
);
232 static SharedPtrGrayImage2
GetAlphaMask(const SharedPtrCClipper
& clipper
);
234 friend class ClipperTraits
;
235 friend class ClipperAlphaMaskCacheKey
;
236 friend class CClipperPaintMachine
;
239 class CLine
: private CAtlList
<SharedPtrCWord
>
242 int m_width
, m_ascent
, m_descent
, m_borderX
, m_borderY
;
249 void AddWord2Tail(SharedPtrCWord words
);
252 CRectCoor2
PaintAll(CompositeDrawItemList
* output
, const CRectCoor2
& clipRect
,
253 const SharedPtrCClipperPaintMachine
&clipper
,
254 CPoint p
, const CPoint
& org
, const int time
, const int alpha
);
257 class CSubtitle
: private CAtlList
<CLine
*>
260 int GetFullLineWidth(POSITION pos
);
261 int GetWrapWidth(POSITION pos
, int maxwidth
);
262 CLine
* GetNextLine(POSITION
& pos
, int maxwidth
);
268 bool m_fAnimated2
; //If this Subtitle has animate effect
271 Effect
* m_effects
[EF_NUMBEROFEFFECTS
];
273 CAtlList
<SharedPtrCWord
> m_words
;
275 SharedPtrCClipper m_pClipper
;
277 CRect m_rect
, m_clip
;
278 int m_topborder
, m_bottomborder
;
281 double m_scalex
, m_scaley
;
282 double m_target_scale_x
, m_target_scale_y
;
285 virtual ~CSubtitle();
286 virtual void Empty();
288 void CreateClippers(CSize size1
, const CSizeCoor2
& size_scale_to
);
290 void MakeLines(CSize size
, CRect marginRect
);
292 POSITION
GetHeadLinePosition();
293 CLine
* GetNextLine(POSITION
& pos
);
298 CSubtitle2():s(NULL
){}
300 CSubtitle2(CSubtitle
* s_
,const CRectCoor2
& clipRect_
, const CPoint
& org_
, const CPoint
& org2_
301 , const CPoint
& p_
, int alpha_
, int time_
)
302 : s(s_
), clipRect(clipRect_
), org(org_
), org2(org2_
), p(p_
), alpha(alpha_
), time(time_
)
308 const CRectCoor2 clipRect
;
316 typedef CAtlList
<CSubtitle2
> CSubtitle2List
;
318 class CScreenLayoutAllocator
323 int segment
, entry
, layer
;
326 CAtlList
<SubRect
> m_subrects
;
329 virtual void Empty();
331 void AdvanceToSegment(int segment
, const CAtlArray
<int>& sa
);
332 CRect
AllocRect(CSubtitle
* s
, int segment
, int entry
, int layer
, int collisions
);
335 [uuid("537DCACA-2812-4a4f-B2C6-1A34C17ADEB0")]
336 class CRenderedTextSubtitle
: public CSubPicProviderImpl
, public ISubStream
, public ISubPicProviderEx2
, public CSimpleTextSubtitle
397 static const int MIN_CMD_LENGTH
= 1;//c etc
398 static const int MAX_CMD_LENGTH
= 5;//alpha, iclip, xbord, xshad, ybord, yshad
399 static CAtlMap
<CStringW
, AssCmdType
, CStringElementTraits
<CStringW
>> m_cmdMap
;
402 typedef CAtlList
<AssTag
> AssTagList
;
403 typedef ::boost::shared_ptr
<const AssTagList
> SharedPtrConstAssTagList
;
407 CAtlArray
<CStringW
> strParams
;
411 CAtlMap
<int, CSubtitle
*> m_subtitleCache
;
413 CScreenLayoutAllocator m_sla
;
415 CSizeCoor2 m_size_scale_to
;
420 // temp variables, used when parsing the script
422 int m_animStart
, m_animEnd
;
424 int m_ktype
, m_kstart
, m_kend
;
426 int m_polygonBaselineOffset
;
428 int m_period
;//1000/m_fps
429 double m_target_scale_x
, m_target_scale_y
;
431 static void InitCmdMap();
433 void ParseEffect(CSubtitle
* sub
, const CString
& str
);
434 void ParseString(CSubtitle
* sub
, CStringW str
, const FwSTSStyle
& style
);
435 void ParsePolygon(CSubtitle
* sub
, const CStringW
& str
, const FwSTSStyle
& style
);
437 static bool ParseSSATag(AssTagList
*assTags
, const CStringW
& str
);
438 bool ParseSSATag(CSubtitle
* sub
, const AssTagList
& assTags
, STSStyle
& style
, const STSStyle
& org
, bool fAnimate
= false);
439 bool ParseSSATag(CSubtitle
* sub
, const CStringW
& str
, STSStyle
& style
, const STSStyle
& org
, bool fAnimate
= false);
441 bool ParseHtmlTag(CSubtitle
* sub
, CStringW str
, STSStyle
& style
, STSStyle
& org
);
443 double CalcAnimation(double dst
, double src
, bool fAnimate
);
445 CSubtitle
* GetSubtitle(int entry
);
448 virtual void OnChanged();
451 CRenderedTextSubtitle(CCritSec
* pLock
);
452 virtual ~CRenderedTextSubtitle();
454 virtual void Copy(CSimpleTextSubtitle
& sts
);
455 virtual void Empty();
458 bool Init(const SIZECoor2
& size_scale_to
, const SIZE
& size1
, const CRect
& video_rect
); // will call Deinit()
462 STDMETHODIMP
NonDelegatingQueryInterface(REFIID riid
, void** ppv
);
464 // ISubPicProviderEx2
466 STDMETHODIMP
Unlock();
467 STDMETHODIMP
RenderEx(IXySubRenderFrame
**subRenderFrame
, int spd_type
,
468 const SIZECoor2
& size_scale_to
,
469 const SIZE
& size1
, const CRect
& video_rect
,
470 REFERENCE_TIME rt
, double fps
);
472 // ISubPicProviderEx && ISubPicProviderEx2
473 STDMETHODIMP_(POSITION
) GetStartPosition(REFERENCE_TIME rt
, double fps
);
474 STDMETHODIMP_(POSITION
) GetNext(POSITION pos
);
475 STDMETHODIMP_(REFERENCE_TIME
) GetStart(POSITION pos
, double fps
);
476 STDMETHODIMP_(REFERENCE_TIME
) GetStop(POSITION pos
, double fps
);
477 STDMETHODIMP_(VOID
) GetStartStop(POSITION pos
, double fps
, /*out*/REFERENCE_TIME
&start
, /*out*/REFERENCE_TIME
&stop
);
478 STDMETHODIMP_(bool) IsAnimated(POSITION pos
);
479 STDMETHODIMP
Render(SubPicDesc
& spd
, REFERENCE_TIME rt
, double fps
, RECTCoor2
& bbox
);
480 STDMETHODIMP
RenderEx(SubPicDesc
& spd
, REFERENCE_TIME rt
, double fps
, CAtlList
<CRectCoor2
>& rectList
);
481 HRESULT
ParseScript(REFERENCE_TIME rt
, double fps
, CSubtitle2List
*outputSub2List
);
482 static void DoRender( const SIZECoor2
& output_size
, const CSubtitle2List
& sub2List
,
483 CompositeDrawItemListList
*compDrawItemListList
/*output*/);
484 static void RenderOneSubtitle(const SIZECoor2
& output_size
, const CSubtitle2
& sub2
,
485 CompositeDrawItemList
* compDrawItemList
/*output*/);
486 STDMETHODIMP_(bool) IsColorTypeSupported(int type
);
489 STDMETHODIMP
GetClassID(CLSID
* pClassID
);
492 STDMETHODIMP_(int) GetStreamCount();
493 STDMETHODIMP
GetStreamInfo(int i
, WCHAR
** ppName
, LCID
* pLCID
);
494 STDMETHODIMP_(int) GetStream();
495 STDMETHODIMP
SetStream(int iStream
);
496 STDMETHODIMP
Reload();