@@ -129,6 +129,28 @@ CWord::CWord(const STSStyle& style, CStringW str, int ktype, int kstart, int ken
129
129
130
130
}
131
131
132
+
133
+ CWord::CWord (RenderingCaches& renderingCaches)
134
+ : m_fDrawn(false )
135
+ , m_p(INT_MAX, INT_MAX)
136
+ , m_renderingCaches(renderingCaches)
137
+ , m_scalex(0 )
138
+ , m_scaley(0 )
139
+ , m_str(L" " )
140
+ , m_fWhiteSpaceChar(false )
141
+ , m_fLineBreak(false )
142
+ , m_style()
143
+ , m_pOpaqueBox(nullptr )
144
+ , m_ktype(0 )
145
+ , m_kstart(0 )
146
+ , m_kend(0 )
147
+ , m_width(0 )
148
+ , m_ascent(0 )
149
+ , m_descent(0 )
150
+ {
151
+ }
152
+
153
+
132
154
CWord::~CWord ()
133
155
{
134
156
delete m_pOpaqueBox;
@@ -603,6 +625,12 @@ CText::CText(const STSStyle& style, CStringW str, int ktype, int kstart, int ken
603
625
m_width = (int )(m_style.fontScaleX / 100 * m_width + 4 ) >> 3 ;
604
626
}
605
627
628
+ // null constructor for use by CLineBG
629
+ CText::CText (RenderingCaches& renderingCaches)
630
+ :CWord(renderingCaches)
631
+ , m_RTS(nullptr ) {
632
+ }
633
+
606
634
CWord* CText::Copy ()
607
635
{
608
636
return DEBUG_NEW CText (*this );
@@ -747,6 +775,118 @@ bool CText::CreatePath()
747
775
return true ;
748
776
}
749
777
778
+
779
+ CLineBG::CLineBG (RenderingCaches& renderingCaches)
780
+ : CText(renderingCaches) {
781
+ }
782
+
783
+ std::shared_ptr<CLineBG> CLineBG::CLineBGFactory (CLine const * line, RenderingCaches& renderingCaches) {
784
+ if (!line || line->GetCount () < 2 ) { // single word does not have need of a combining algorithm
785
+ return nullptr ;
786
+ }
787
+
788
+
789
+ std::shared_ptr<CLineBG> lineBG = std::make_shared<CLineBG>(renderingCaches);
790
+
791
+ bool first = true ;
792
+ POSITION pos = line->GetHeadPosition ();
793
+ while (pos) {
794
+ CWord* w = line->GetNext (pos);
795
+ if (first) {
796
+ if (w->m_style .borderStyle == 0 ) {
797
+ return nullptr ;
798
+ }
799
+
800
+ lineBG->m_scalex = w->m_scalex ;
801
+ lineBG->m_scaley = w->m_scaley ;
802
+ lineBG->m_str = w->m_str ;
803
+ lineBG->m_style = w->m_style ;
804
+ lineBG->m_ktype = w->m_ktype ;
805
+ lineBG->m_kstart = w->m_kstart ;
806
+ lineBG->m_kend = w->m_kend ;
807
+ lineBG->m_width = w->m_width ;
808
+ lineBG->m_ascent = w->m_ascent ;
809
+ lineBG->m_descent = w->m_descent ;
810
+ first = false ;
811
+ } else if (lineBG->m_scalex != w->m_scalex ||
812
+ lineBG->m_scaley != w->m_scaley ||
813
+ lineBG->m_ktype != w->m_ktype ||
814
+ lineBG->m_kstart != w->m_kstart ||
815
+ lineBG->m_kend != w->m_kend ||
816
+ lineBG->m_ascent != w->m_ascent ||
817
+ lineBG->m_descent != w->m_descent ) {
818
+ return nullptr ; // to combine words into one line, we currently restrict it to words who have identical properties
819
+ } else {
820
+ // check style
821
+ STSStyle s1 (lineBG->m_style );
822
+ STSStyle s2 (w->m_style );
823
+ // everything in style must match except these properties
824
+ s2.fontWeight = s1.fontWeight ;
825
+ s2.fItalic = s1.fItalic ;
826
+ s2.fUnderline = s1.fUnderline ;
827
+ s2.fStrikeOut = s1.fStrikeOut ;
828
+
829
+ if (s2 != s1) {
830
+ return nullptr ;
831
+ }
832
+ lineBG->m_width += w->m_width ;
833
+ }
834
+ }
835
+ return lineBG;
836
+ }
837
+
838
+ // see CLine::PaintShadow
839
+ CRect CLineBG::PaintLineShadow (SubPicDesc& spd, CRect& clipRect, BYTE* pAlphaMask, CPoint p, CPoint org, int time, int alpha) {
840
+ CRect bbox (0 , 0 , 0 , 0 );
841
+
842
+ if (m_style.shadowDepthX != 0 || m_style.shadowDepthY != 0 ) {
843
+ int x = p.x + (int )(m_style.shadowDepthX + 0.5 );
844
+ int y = p.y + m_ascent - m_ascent + (int )(m_style.shadowDepthY + 0.5 );
845
+
846
+ DWORD a = 0xff - m_style.alpha [3 ];
847
+ if (alpha > 0 ) {
848
+ a = a * (0xff - static_cast <DWORD>(alpha)) / 0xff ;
849
+ }
850
+ COLORREF shadow = revcolor (m_style.colors [3 ]) | (a << 24 );
851
+ DWORD sw[6 ] = { shadow, DWORD_MAX };
852
+ sw[0 ] = ColorConvTable::ColorCorrection (sw[0 ]);
853
+
854
+ Paint (CPoint (x, y), org);
855
+
856
+ if (m_style.borderStyle == 1 && m_pOpaqueBox) {
857
+ bbox |= m_pOpaqueBox->Draw (spd, clipRect, pAlphaMask, x, y, sw, true , false );
858
+ }
859
+ }
860
+
861
+ return bbox;
862
+ }
863
+
864
+
865
+ // see CLine::PaintOutline
866
+ CRect CLineBG::PaintLineOutline (SubPicDesc& spd, CRect& clipRect, BYTE* pAlphaMask, CPoint p, CPoint org, int time, int alpha) {
867
+ CRect bbox (0 , 0 , 0 , 0 );
868
+
869
+ bool has_outline = m_style.outlineWidthX + m_style.outlineWidthY > 0.0 ;
870
+ if ((has_outline || m_style.borderStyle == 1 ) && !(m_ktype == 2 && time < m_kstart)) {
871
+ int x = p.x ;
872
+ int y = p.y + m_ascent - m_ascent;
873
+ DWORD aoutline = m_style.alpha [2 ];
874
+ if (alpha > 0 ) {
875
+ aoutline += alpha * (0xff - m_style.alpha [2 ]) / 0xff ;
876
+ }
877
+ COLORREF outline = revcolor (has_outline ? m_style.colors [2 ] : m_style.colors [3 ]) | ((0xff - aoutline) << 24 );
878
+ DWORD sw[6 ] = { outline, DWORD_MAX };
879
+ sw[0 ] = ColorConvTable::ColorCorrection (sw[0 ]);
880
+
881
+ Paint (CPoint (x, y), org);
882
+ if (m_style.borderStyle == 1 && m_pOpaqueBox) {
883
+ bbox |= m_pOpaqueBox->Draw (spd, clipRect, pAlphaMask, x, y, sw, true , false );
884
+ }
885
+ }
886
+
887
+ return bbox;
888
+ }
889
+
750
890
// CPolygon
751
891
752
892
CPolygon::CPolygon (const STSStyle& style, CStringW str, int ktype, int kstart, int kend, double scalex, double scaley, int baseline,
@@ -1255,6 +1395,7 @@ void CLine::Compact()
1255
1395
}
1256
1396
}
1257
1397
1398
+ // note that CLineBG::PaintLineShadow is derived from this code and should be updated if this is changed
1258
1399
CRect CLine::PaintShadow (SubPicDesc& spd, CRect& clipRect, BYTE* pAlphaMask, CPoint p, CPoint org, int time, int alpha)
1259
1400
{
1260
1401
CRect bbox (0 , 0 , 0 , 0 );
@@ -1296,6 +1437,7 @@ CRect CLine::PaintShadow(SubPicDesc& spd, CRect& clipRect, BYTE* pAlphaMask, CPo
1296
1437
return bbox;
1297
1438
}
1298
1439
1440
+ // note that CLineBG::PaintLineOutline is derived from this code and should be updated if this is changed
1299
1441
CRect CLine::PaintOutline (SubPicDesc& spd, CRect& clipRect, BYTE* pAlphaMask, CPoint p, CPoint org, int time, int alpha)
1300
1442
{
1301
1443
CRect bbox (0 , 0 , 0 , 0 );
@@ -3554,8 +3696,14 @@ STDMETHODIMP CRenderedTextSubtitle::Render(SubPicDesc& spd, REFERENCE_TIME rt, d
3554
3696
}
3555
3697
} else {
3556
3698
if (paintBG) {
3557
- bbox2 |= l->PaintShadow (spd, clipRect, pAlphaMask, p, org2, m_time, alpha);
3558
- bbox2 |= l->PaintOutline (spd, clipRect, pAlphaMask, p, org2, m_time, alpha);
3699
+ auto lineBG = CLineBG::CLineBGFactory (l, m_renderingCaches);
3700
+ if (lineBG) {
3701
+ bbox2 |= lineBG->PaintLineShadow (spd, clipRect, pAlphaMask, p, org2, m_time, alpha);
3702
+ bbox2 |= lineBG->PaintLineOutline (spd, clipRect, pAlphaMask, p, org2, m_time, alpha);
3703
+ } else {
3704
+ bbox2 |= l->PaintShadow (spd, clipRect, pAlphaMask, p, org2, m_time, alpha);
3705
+ bbox2 |= l->PaintOutline (spd, clipRect, pAlphaMask, p, org2, m_time, alpha);
3706
+ }
3559
3707
}
3560
3708
if (paintBody) {
3561
3709
bbox2 |= l->PaintBody (spd, clipRect, pAlphaMask, p, org2, m_time, alpha);
0 commit comments