Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
234c3fab
Commit
234c3fab
authored
Sep 03, 2012
by
Felix Paul Kühne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
quartztext: unify and modernize coding style
parent
da06d2cb
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
356 additions
and
423 deletions
+356
-423
modules/text_renderer/quartztext.c
modules/text_renderer/quartztext.c
+356
-423
No files found.
modules/text_renderer/quartztext.c
View file @
234c3fab
...
@@ -21,9 +21,9 @@
...
@@ -21,9 +21,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
*****************************************************************************/
/
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
//
Preamble
*
Preamble
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include "config.h"
# include "config.h"
...
@@ -57,47 +57,47 @@
...
@@ -57,47 +57,47 @@
#define VERTICAL_MARGIN 3
#define VERTICAL_MARGIN 3
#define HORIZONTAL_MARGIN 10
#define HORIZONTAL_MARGIN 10
/
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
//
Local prototypes
*
Local prototypes
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
/
static
int
Create
(
vlc_object_t
*
);
static
int
Create
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_t
*
);
static
int
LoadFontsFromAttachments
(
filter_t
*
p_filter
);
static
int
LoadFontsFromAttachments
(
filter_t
*
p_filter
);
static
int
RenderText
(
filter_t
*
,
subpicture_region_t
*
,
static
int
RenderText
(
filter_t
*
,
subpicture_region_t
*
,
subpicture_region_t
*
,
subpicture_region_t
*
,
const
vlc_fourcc_t
*
);
const
vlc_fourcc_t
*
);
static
int
RenderHtml
(
filter_t
*
,
subpicture_region_t
*
,
static
int
RenderHtml
(
filter_t
*
,
subpicture_region_t
*
,
subpicture_region_t
*
,
subpicture_region_t
*
,
const
vlc_fourcc_t
*
);
const
vlc_fourcc_t
*
);
static
int
GetFontSize
(
filter_t
*
p_filter
);
static
int
GetFontSize
(
filter_t
*
p_filter
);
static
int
RenderYUVA
(
filter_t
*
p_filter
,
subpicture_region_t
*
p_region
,
static
int
RenderYUVA
(
filter_t
*
p_filter
,
subpicture_region_t
*
p_region
,
CFMutableAttributedStringRef
p_attrString
);
CFMutableAttributedStringRef
p_attrString
);
static
void
setFontAttibutes
(
char
*
psz_fontname
,
int
i_font_size
,
uint32_t
i_font_color
,
static
void
setFontAttibutes
(
char
*
psz_fontname
,
int
i_font_size
,
uint32_t
i_font_color
,
bool
b_bold
,
bool
b_italic
,
bool
b_underline
,
bool
b_bold
,
bool
b_italic
,
bool
b_underline
,
CFRange
p_range
,
CFMutableAttributedStringRef
p_attrString
);
CFRange
p_range
,
CFMutableAttributedStringRef
p_attrString
);
/
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
//
Module descriptor
*
Module descriptor
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
/
/
/
The preferred way to set font style information is for it to come from the
/
*
The preferred way to set font style information is for it to come from the
//
subtitle file, and for it to be rendered with RenderHtml instead of
*
subtitle file, and for it to be rendered with RenderHtml instead of
// RenderText.
* RenderText. */
#define FONT_TEXT N_("Font")
#define FONT_TEXT N_("Font")
#define FONT_LONGTEXT N_("Name for the font you want to use")
#define FONT_LONGTEXT N_("Name for the font you want to use")
#define FONTSIZER_TEXT N_("Relative font size")
#define FONTSIZER_TEXT N_("Relative font size")
#define FONTSIZER_LONGTEXT N_("This is the relative default size of the " \
#define FONTSIZER_LONGTEXT N_("This is the relative default size of the " \
"fonts that will be rendered on the video. If absolute font size is set, "\
"fonts that will be rendered on the video. If absolute font size is set, "\
"relative size will be overridden."
)
"relative size will be overridden.")
#define COLOR_TEXT N_("Text default color")
#define COLOR_TEXT N_("Text default color")
#define COLOR_LONGTEXT N_("The color of the text that will be rendered on "\
#define COLOR_LONGTEXT N_("The color of the text that will be rendered on "\
"the video. This must be an hexadecimal (like HTML colors). The first two "\
"the video. This must be an hexadecimal (like HTML colors). The first two "\
"chars are for red, then green, then blue. #000000 = black, #FF0000 = red,"\
"chars are for red, then green, then blue. #000000 = black, #FF0000 = red,"\
" #00FF00 = green, #FFFF00 = yellow (red + green), #FFFFFF = white"
)
" #00FF00 = green, #FFFF00 = yellow (red + green), #FFFFFF = white")
static
const
int
pi_color_values
[]
=
{
static
const
int
pi_color_values
[]
=
{
0x00000000
,
0x00808080
,
0x00C0C0C0
,
0x00FFFFFF
,
0x00800000
,
0x00000000
,
0x00808080
,
0x00C0C0C0
,
0x00FFFFFF
,
0x00800000
,
...
@@ -114,22 +114,22 @@ static const char *const ppsz_sizes_text[] = {
...
@@ -114,22 +114,22 @@ static const char *const ppsz_sizes_text[] = {
N_
(
"Smaller"
),
N_
(
"Small"
),
N_
(
"Normal"
),
N_
(
"Large"
),
N_
(
"Larger"
)
};
N_
(
"Smaller"
),
N_
(
"Small"
),
N_
(
"Normal"
),
N_
(
"Large"
),
N_
(
"Larger"
)
};
vlc_module_begin
()
vlc_module_begin
()
set_shortname
(
N_
(
"Text renderer for Mac"
))
set_shortname
(
N_
(
"Text renderer for Mac"
))
set_description
(
N_
(
"CoreText font renderer"
)
)
set_description
(
N_
(
"CoreText font renderer"
)
)
set_category
(
CAT_VIDEO
)
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_SUBPIC
)
set_subcategory
(
SUBCAT_VIDEO_SUBPIC
)
add_string
(
"quartztext-font"
,
DEFAULT_FONT
,
FONT_TEXT
,
FONT_LONGTEXT
,
add_string
(
"quartztext-font"
,
DEFAULT_FONT
,
FONT_TEXT
,
FONT_LONGTEXT
,
false
)
false
)
add_integer
(
"quartztext-rel-fontsize"
,
DEFAULT_REL_FONT_SIZE
,
FONTSIZER_TEXT
,
add_integer
(
"quartztext-rel-fontsize"
,
DEFAULT_REL_FONT_SIZE
,
FONTSIZER_TEXT
,
FONTSIZER_LONGTEXT
,
false
)
FONTSIZER_LONGTEXT
,
false
)
change_integer_list
(
pi_sizes
,
ppsz_sizes_text
)
change_integer_list
(
pi_sizes
,
ppsz_sizes_text
)
add_integer
(
"quartztext-color"
,
0x00FFFFFF
,
COLOR_TEXT
,
add_integer
(
"quartztext-color"
,
0x00FFFFFF
,
COLOR_TEXT
,
COLOR_LONGTEXT
,
false
)
COLOR_LONGTEXT
,
false
)
change_integer_list
(
pi_color_values
,
ppsz_color_descriptions
)
change_integer_list
(
pi_color_values
,
ppsz_color_descriptions
)
set_capability
(
"text renderer"
,
50
)
set_capability
(
"text renderer"
,
50
)
add_shortcut
(
"text"
)
add_shortcut
(
"text"
)
set_callbacks
(
Create
,
Destroy
)
set_callbacks
(
Create
,
Destroy
)
vlc_module_end
()
vlc_module_end
()
typedef
struct
font_stack_t
font_stack_t
;
typedef
struct
font_stack_t
font_stack_t
;
...
@@ -162,12 +162,12 @@ struct offscreen_bitmap_t
...
@@ -162,12 +162,12 @@ struct offscreen_bitmap_t
int
i_bytesPerRow
;
int
i_bytesPerRow
;
};
};
/
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
//
filter_sys_t: quartztext local data
*
filter_sys_t: quartztext local data
//////////////////////////////////////////////////////////////////////////////
*****************************************************************************
//
This structure is part of the video output thread descriptor.
*
This structure is part of the video output thread descriptor.
//
It describes the freetype specific properties of an output thread.
*
It describes the freetype specific properties of an output thread.
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
/
struct
filter_sys_t
struct
filter_sys_t
{
{
char
*
psz_font_name
;
char
*
psz_font_name
;
...
@@ -181,24 +181,24 @@ struct filter_sys_t
...
@@ -181,24 +181,24 @@ struct filter_sys_t
#endif
#endif
};
};
/
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
//
Create: allocates osd-text video thread output method
*
Create: allocates osd-text video thread output method
//////////////////////////////////////////////////////////////////////////////
*****************************************************************************
//
This function allocates and initializes a Clone vout method.
*
This function allocates and initializes a Clone vout method.
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
/
static
int
Create
(
vlc_object_t
*
p_this
)
static
int
Create
(
vlc_object_t
*
p_this
)
{
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
;
filter_sys_t
*
p_sys
;
// Allocate structure
// Allocate structure
p_filter
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
filter_sys_t
)
);
p_filter
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
filter_sys_t
)
);
if
(
!
p_sys
)
if
(
!
p_sys
)
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
p_sys
->
psz_font_name
=
var_CreateGetString
(
p_this
,
"quartztext-font"
);
p_sys
->
psz_font_name
=
var_CreateGetString
(
p_this
,
"quartztext-font"
);
p_sys
->
i_font_opacity
=
255
;
p_sys
->
i_font_opacity
=
255
;
p_sys
->
i_font_color
=
VLC_CLIP
(
var_CreateGetInteger
(
p_this
,
"quartztext-color"
)
,
0
,
0xFFFFFF
);
p_sys
->
i_font_color
=
VLC_CLIP
(
var_CreateGetInteger
(
p_this
,
"quartztext-color"
)
,
0
,
0xFFFFFF
);
p_sys
->
i_font_size
=
GetFontSize
(
p_filter
);
p_sys
->
i_font_size
=
GetFontSize
(
p_filter
);
p_filter
->
pf_render_text
=
RenderText
;
p_filter
->
pf_render_text
=
RenderText
;
p_filter
->
pf_render_html
=
RenderHtml
;
p_filter
->
pf_render_html
=
RenderHtml
;
...
@@ -208,42 +208,37 @@ static int Create( vlc_object_t *p_this )
...
@@ -208,42 +208,37 @@ static int Create( vlc_object_t *p_this )
p_sys
->
i_fonts
=
0
;
p_sys
->
i_fonts
=
0
;
#endif
#endif
LoadFontsFromAttachments
(
p_filter
);
LoadFontsFromAttachments
(
p_filter
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
/
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
//
Destroy: destroy Clone video thread output method
*
Destroy: destroy Clone video thread output method
//////////////////////////////////////////////////////////////////////////////
*****************************************************************************
//
Clean up all data and library connections
*
Clean up all data and library connections
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
/
static
void
Destroy
(
vlc_object_t
*
p_this
)
static
void
Destroy
(
vlc_object_t
*
p_this
)
{
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
#ifndef TARGET_OS_IPHONE
#ifndef TARGET_OS_IPHONE
if
(
p_sys
->
p_fonts
)
if
(
p_sys
->
p_fonts
)
{
{
for
(
int
k
=
0
;
k
<
p_sys
->
i_fonts
;
k
++
)
{
int
k
;
ATSFontDeactivate
(
p_sys
->
p_fonts
[
k
],
NULL
,
kATSOptionFlagsDefault
)
;
for
(
k
=
0
;
k
<
p_sys
->
i_fonts
;
k
++
)
free
(
p_sys
->
p_fonts
);
{
ATSFontDeactivate
(
p_sys
->
p_fonts
[
k
],
NULL
,
kATSOptionFlagsDefault
);
}
free
(
p_sys
->
p_fonts
);
}
}
#endif
#endif
free
(
p_sys
->
psz_font_name
);
free
(
p_sys
->
psz_font_name
);
free
(
p_sys
);
free
(
p_sys
);
}
}
/
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
//
Make any TTF/OTF fonts present in the attachments of the media file
*
Make any TTF/OTF fonts present in the attachments of the media file
//
available to the Quartz engine for text rendering
*
available to the Quartz engine for text rendering
/////////////////////////////////////////////////////////////////////////////
/
*****************************************************************************
/
static
int
LoadFontsFromAttachments
(
filter_t
*
p_filter
)
static
int
LoadFontsFromAttachments
(
filter_t
*
p_filter
)
{
{
#ifdef TARGET_OS_IPHONE
#ifdef TARGET_OS_IPHONE
VLC_UNUSED
(
p_filter
);
VLC_UNUSED
(
p_filter
);
...
@@ -253,65 +248,58 @@ static int LoadFontsFromAttachments( filter_t *p_filter )
...
@@ -253,65 +248,58 @@ static int LoadFontsFromAttachments( filter_t *p_filter )
input_attachment_t
**
pp_attachments
;
input_attachment_t
**
pp_attachments
;
int
i_attachments_cnt
;
int
i_attachments_cnt
;
if
(
filter_GetInputAttachments
(
p_filter
,
&
pp_attachments
,
&
i_attachments_cnt
)
)
if
(
filter_GetInputAttachments
(
p_filter
,
&
pp_attachments
,
&
i_attachments_cnt
)
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
p_sys
->
i_fonts
=
0
;
p_sys
->
i_fonts
=
0
;
p_sys
->
p_fonts
=
malloc
(
i_attachments_cnt
*
sizeof
(
ATSFontContainerRef
)
);
p_sys
->
p_fonts
=
malloc
(
i_attachments_cnt
*
sizeof
(
ATSFontContainerRef
)
);
if
(
!
p_sys
->
p_fonts
)
if
(
!
p_sys
->
p_fonts
)
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
for
(
int
k
=
0
;
k
<
i_attachments_cnt
;
k
++
)
for
(
int
k
=
0
;
k
<
i_attachments_cnt
;
k
++
)
{
{
input_attachment_t
*
p_attach
=
pp_attachments
[
k
];
input_attachment_t
*
p_attach
=
pp_attachments
[
k
];
if
(
(
!
strcmp
(
p_attach
->
psz_mime
,
"application/x-truetype-font"
)
||
// TTF
if
((
!
strcmp
(
p_attach
->
psz_mime
,
"application/x-truetype-font"
)
||
// TTF
!
strcmp
(
p_attach
->
psz_mime
,
"application/x-font-otf"
)
)
&&
// OTF
!
strcmp
(
p_attach
->
psz_mime
,
"application/x-font-otf"
))
&&
// OTF
p_attach
->
i_data
>
0
&&
p_attach
->
p_data
)
p_attach
->
i_data
>
0
&&
p_attach
->
p_data
)
{
{
ATSFontContainerRef
container
;
ATSFontContainerRef
container
;
if
(
noErr
==
ATSFontActivateFromMemory
(
p_attach
->
p_data
,
if
(
noErr
==
ATSFontActivateFromMemory
(
p_attach
->
p_data
,
p_attach
->
i_data
,
p_attach
->
i_data
,
kATSFontContextLocal
,
kATSFontContextLocal
,
kATSFontFormatUnspecified
,
kATSFontFormatUnspecified
,
NULL
,
NULL
,
kATSOptionFlagsDefault
,
kATSOptionFlagsDefault
,
&
container
))
&
container
))
{
p_sys
->
p_fonts
[
p_sys
->
i_fonts
++
]
=
container
;
p_sys
->
p_fonts
[
p_sys
->
i_fonts
++
]
=
container
;
}
}
}
vlc_input_attachment_Delete
(
p_attach
);
vlc_input_attachment_Delete
(
p_attach
);
}
}
free
(
pp_attachments
);
free
(
pp_attachments
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
#endif
#endif
}
}
static
char
*
EliminateCRLF
(
char
*
psz_string
)
static
char
*
EliminateCRLF
(
char
*
psz_string
)
{
{
char
*
p
;
char
*
q
;
char
*
q
;
for
(
p
=
psz_string
;
p
&&
*
p
;
p
++
)
for
(
char
*
p
=
psz_string
;
p
&&
*
p
;
p
++
)
{
{
if
((
*
p
==
'\r'
)
&&
(
*
(
p
+
1
)
==
'\n'
))
{
if
(
(
*
p
==
'\r'
)
&&
(
*
(
p
+
1
)
==
'\n'
)
)
for
(
q
=
p
+
1
;
*
q
;
q
++
)
{
*
(
q
-
1
)
=
*
q
;
for
(
q
=
p
+
1
;
*
q
;
q
++
)
*
(
q
-
1
)
=
*
q
;
*
(
q
-
1
)
=
'\0'
;
*
(
q
-
1
)
=
'\0'
;
}
}
}
}
return
psz_string
;
return
psz_string
;
}
}
/
/
Renders a text subpicture region into another one.
/
*
Renders a text subpicture region into another one.
// It is used as pf_add_string callback in the vout method by this module
* It is used as pf_add_string callback in the vout method by this module */
static
int
RenderText
(
filter_t
*
p_filter
,
subpicture_region_t
*
p_region_out
,
static
int
RenderText
(
filter_t
*
p_filter
,
subpicture_region_t
*
p_region_out
,
subpicture_region_t
*
p_region_in
,
subpicture_region_t
*
p_region_in
,
const
vlc_fourcc_t
*
p_chroma_list
)
const
vlc_fourcc_t
*
p_chroma_list
)
{
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
char
*
psz_string
;
char
*
psz_string
;
...
@@ -321,41 +309,40 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,
...
@@ -321,41 +309,40 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,
vlc_value_t
val
;
vlc_value_t
val
;
b_bold
=
b_uline
=
b_italic
=
FALSE
;
b_bold
=
b_uline
=
b_italic
=
FALSE
;
p_sys
->
i_font_size
=
GetFontSize
(
p_filter
);
p_sys
->
i_font_size
=
GetFontSize
(
p_filter
);
// Sanity check
// Sanity check
if
(
!
p_region_in
||
!
p_region_out
)
return
VLC_EGENERIC
;
if
(
!
p_region_in
||
!
p_region_out
)
return
VLC_EGENERIC
;
psz_string
=
p_region_in
->
psz_text
;
psz_string
=
p_region_in
->
psz_text
;
if
(
!
psz_string
||
!*
psz_string
)
return
VLC_EGENERIC
;
if
(
!
psz_string
||
!*
psz_string
)
return
VLC_EGENERIC
;
if
(
p_region_in
->
p_style
)
{
if
(
p_region_in
->
p_style
)
{
i_font_color
=
VLC_CLIP
(
p_region_in
->
p_style
->
i_font_color
,
0
,
0xFFFFFF
);
i_font_color
=
VLC_CLIP
(
p_region_in
->
p_style
->
i_font_color
,
0
,
0xFFFFFF
);
i_font_alpha
=
VLC_CLIP
(
p_region_in
->
p_style
->
i_font_alpha
,
0
,
255
);
i_font_alpha
=
VLC_CLIP
(
p_region_in
->
p_style
->
i_font_alpha
,
0
,
255
);
i_font_size
=
VLC_CLIP
(
p_region_in
->
p_style
->
i_font_size
,
0
,
255
);
i_font_size
=
VLC_CLIP
(
p_region_in
->
p_style
->
i_font_size
,
0
,
255
);
if
(
p_region_in
->
p_style
->
i_style_flags
)
if
(
p_region_in
->
p_style
->
i_style_flags
)
{
{
if
(
p_region_in
->
p_style
->
i_style_flags
&
STYLE_BOLD
)
if
(
p_region_in
->
p_style
->
i_style_flags
&
STYLE_BOLD
)
b_bold
=
TRUE
;
b_bold
=
TRUE
;
if
(
p_region_in
->
p_style
->
i_style_flags
&
STYLE_ITALIC
)
if
(
p_region_in
->
p_style
->
i_style_flags
&
STYLE_ITALIC
)
b_italic
=
TRUE
;
b_italic
=
TRUE
;
if
(
p_region_in
->
p_style
->
i_style_flags
&
STYLE_UNDERLINE
)
if
(
p_region_in
->
p_style
->
i_style_flags
&
STYLE_UNDERLINE
)
b_uline
=
TRUE
;
b_uline
=
TRUE
;
}
}
}
}
else
{
else
{
i_font_color
=
p_sys
->
i_font_color
;
i_font_color
=
p_sys
->
i_font_color
;
i_font_alpha
=
255
-
p_sys
->
i_font_opacity
;
i_font_alpha
=
255
-
p_sys
->
i_font_opacity
;
i_font_size
=
p_sys
->
i_font_size
;
i_font_size
=
p_sys
->
i_font_size
;
}
}
if
(
!
i_font_alpha
)
i_font_alpha
=
255
-
p_sys
->
i_font_opacity
;
if
(
!
i_font_alpha
)
i_font_alpha
=
255
-
p_sys
->
i_font_opacity
;
if
(
i_font_size
<=
0
)
if
(
i_font_size
<=
0
)
{
{
msg_Warn
(
p_filter
,
"invalid fontsize, using 12"
);
msg_Warn
(
p_filter
,
"invalid fontsize, using 12"
);
if
(
VLC_SUCCESS
==
var_Get
(
p_filter
,
"scale"
,
&
val
))
if
(
VLC_SUCCESS
==
var_Get
(
p_filter
,
"scale"
,
&
val
))
i_font_size
=
12
*
val
.
i_int
/
1000
;
i_font_size
=
12
*
val
.
i_int
/
1000
;
else
else
i_font_size
=
12
;
i_font_size
=
12
;
...
@@ -366,61 +353,55 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,
...
@@ -366,61 +353,55 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,
CFMutableAttributedStringRef
p_attrString
=
CFAttributedStringCreateMutable
(
kCFAllocatorDefault
,
0
);
CFMutableAttributedStringRef
p_attrString
=
CFAttributedStringCreateMutable
(
kCFAllocatorDefault
,
0
);
if
(
p_attrString
)
if
(
p_attrString
)
{
{
CFStringRef
p_cfString
;
CFStringRef
p_cfString
;
int
len
;
int
len
;
EliminateCRLF
(
psz_string
);
EliminateCRLF
(
psz_string
);
p_cfString
=
CFStringCreateWithCString
(
NULL
,
psz_string
,
kCFStringEncodingUTF8
);
p_cfString
=
CFStringCreateWithCString
(
NULL
,
psz_string
,
kCFStringEncodingUTF8
);
CFAttributedStringReplaceString
(
p_attrString
,
CFRangeMake
(
0
,
0
),
p_cfString
);
CFAttributedStringReplaceString
(
p_attrString
,
CFRangeMake
(
0
,
0
),
p_cfString
);
CFRelease
(
p_cfString
);
CFRelease
(
p_cfString
);
len
=
CFAttributedStringGetLength
(
p_attrString
);
len
=
CFAttributedStringGetLength
(
p_attrString
);
setFontAttibutes
(
p_sys
->
psz_font_name
,
i_font_size
,
i_font_color
,
b_bold
,
b_italic
,
b_uline
,
setFontAttibutes
(
p_sys
->
psz_font_name
,
i_font_size
,
i_font_color
,
b_bold
,
b_italic
,
b_uline
,
CFRangeMake
(
0
,
len
),
p_attrString
);
CFRangeMake
(
0
,
len
),
p_attrString
);
RenderYUVA
(
p_filter
,
p_region_out
,
p_attrString
);
RenderYUVA
(
p_filter
,
p_region_out
,
p_attrString
);
CFRelease
(
p_attrString
);
CFRelease
(
p_attrString
);
}
}
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
static
int
PushFont
(
font_stack_t
**
p_font
,
const
char
*
psz_name
,
int
i_size
,
static
int
PushFont
(
font_stack_t
**
p_font
,
const
char
*
psz_name
,
int
i_size
,
uint32_t
i_color
)
uint32_t
i_color
)
{
{
font_stack_t
*
p_new
;
font_stack_t
*
p_new
;
if
(
!
p_font
)
if
(
!
p_font
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
p_new
=
malloc
(
sizeof
(
font_stack_t
)
);
p_new
=
malloc
(
sizeof
(
font_stack_t
)
);
if
(
!
p_new
)
if
(
!
p_new
)
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
p_new
->
p_next
=
NULL
;
p_new
->
p_next
=
NULL
;
if
(
psz_name
)
if
(
psz_name
)
p_new
->
psz_name
=
strdup
(
psz_name
);
p_new
->
psz_name
=
strdup
(
psz_name
);
else
else
p_new
->
psz_name
=
NULL
;
p_new
->
psz_name
=
NULL
;
p_new
->
i_size
=
i_size
;
p_new
->
i_size
=
i_size
;
p_new
->
i_color
=
i_color
;
p_new
->
i_color
=
i_color
;
if
(
!*
p_font
)
if
(
!*
p_font
)
{
*
p_font
=
p_new
;
*
p_font
=
p_new
;
}
else
{
else
{
font_stack_t
*
p_last
;
font_stack_t
*
p_last
;
for
(
p_last
=
*
p_font
;
for
(
p_last
=
*
p_font
;
p_last
->
p_next
;
p_last
=
p_last
->
p_next
)
p_last
->
p_next
;
p_last
=
p_last
->
p_next
)
;
;
p_last
->
p_next
=
p_new
;
p_last
->
p_next
=
p_new
;
...
@@ -428,43 +409,39 @@ static int PushFont( font_stack_t **p_font, const char *psz_name, int i_size,
...
@@ -428,43 +409,39 @@ static int PushFont( font_stack_t **p_font, const char *psz_name, int i_size,
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
static
int
PopFont
(
font_stack_t
**
p_font
)
static
int
PopFont
(
font_stack_t
**
p_font
)
{
{
font_stack_t
*
p_last
,
*
p_next_to_last
;
font_stack_t
*
p_last
,
*
p_next_to_last
;
if
(
!
p_font
||
!*
p_font
)
if
(
!
p_font
||
!*
p_font
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
p_next_to_last
=
NULL
;
p_next_to_last
=
NULL
;
for
(
p_last
=
*
p_font
;
for
(
p_last
=
*
p_font
;
p_last
->
p_next
;
p_last
=
p_last
->
p_next
)
p_last
->
p_next
;
p_last
=
p_last
->
p_next
)
{
p_next_to_last
=
p_last
;
p_next_to_last
=
p_last
;
}
if
(
p_next_to_last
)
if
(
p_next_to_last
)
p_next_to_last
->
p_next
=
NULL
;
p_next_to_last
->
p_next
=
NULL
;
else
else
*
p_font
=
NULL
;
*
p_font
=
NULL
;
free
(
p_last
->
psz_name
);
free
(
p_last
->
psz_name
);
free
(
p_last
);
free
(
p_last
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
static
int
PeekFont
(
font_stack_t
**
p_font
,
char
**
psz_name
,
int
*
i_size
,
static
int
PeekFont
(
font_stack_t
**
p_font
,
char
**
psz_name
,
int
*
i_size
,
uint32_t
*
i_color
)
uint32_t
*
i_color
)
{
{
font_stack_t
*
p_last
;
font_stack_t
*
p_last
;
if
(
!
p_font
||
!*
p_font
)
if
(
!
p_font
||
!*
p_font
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
for
(
p_last
=*
p_font
;
for
(
p_last
=*
p_font
;
p_last
->
p_next
;
p_last
->
p_next
;
p_last
=
p_last
->
p_next
)
p_last
=
p_last
->
p_next
)
;
;
*
psz_name
=
p_last
->
psz_name
;
*
psz_name
=
p_last
->
psz_name
;
...
@@ -474,8 +451,8 @@ static int PeekFont( font_stack_t **p_font, char **psz_name, int *i_size,
...
@@ -474,8 +451,8 @@ static int PeekFont( font_stack_t **p_font, char **psz_name, int *i_size,
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
static
int
HandleFontAttributes
(
xml_reader_t
*
p_xml_reader
,
static
int
HandleFontAttributes
(
xml_reader_t
*
p_xml_reader
,
font_stack_t
**
p_fonts
)
font_stack_t
**
p_fonts
)
{
{
int
rv
;
int
rv
;
char
*
psz_fontname
=
NULL
;
char
*
psz_fontname
=
NULL
;
...
@@ -484,167 +461,156 @@ static int HandleFontAttributes( xml_reader_t *p_xml_reader,
...
@@ -484,167 +461,156 @@ static int HandleFontAttributes( xml_reader_t *p_xml_reader,
int
i_font_size
=
24
;
int
i_font_size
=
24
;
const
char
*
attr
,
*
value
;
const
char
*
attr
,
*
value
;
// Default all attributes to the top font in the stack -- in case not
/* Default all attributes to the top font in the stack -- in case not
// all attributes are specified in the sub-font
* all attributes are specified in the sub-font */
if
(
VLC_SUCCESS
==
PeekFont
(
p_fonts
,
if
(
VLC_SUCCESS
==
PeekFont
(
p_fonts
,
&
psz_fontname
,
&
psz_fontname
,
&
i_font_size
,
&
i_font_size
,
&
i_font_color
))
&
i_font_color
))
{
{
psz_fontname
=
strdup
(
psz_fontname
);
psz_fontname
=
strdup
(
psz_fontname
);
i_font_size
=
i_font_size
;
i_font_size
=
i_font_size
;
}
}
i_font_alpha
=
(
i_font_color
>>
24
)
&
0xff
;
i_font_alpha
=
(
i_font_color
>>
24
)
&
0xff
;
i_font_color
&=
0x00ffffff
;
i_font_color
&=
0x00ffffff
;
while
(
(
attr
=
xml_ReaderNextAttr
(
p_xml_reader
,
&
value
))
)
while
((
attr
=
xml_ReaderNextAttr
(
p_xml_reader
,
&
value
)))
{
{
if
(
!
strcasecmp
(
"face"
,
attr
))
{
if
(
!
strcasecmp
(
"face"
,
attr
)
)
free
(
psz_fontname
);
{
psz_fontname
=
strdup
(
value
);
free
(
psz_fontname
);
}
else
if
(
!
strcasecmp
(
"size"
,
attr
))
{
psz_fontname
=
strdup
(
value
);
if
((
*
value
==
'+'
)
||
(
*
value
==
'-'
))
{
}
int
i_value
=
atoi
(
value
);
else
if
(
!
strcasecmp
(
"size"
,
attr
)
)
{
if
((
i_value
>=
-
5
)
&&
(
i_value
<=
5
))
if
(
(
*
value
==
'+'
)
||
(
*
value
==
'-'
)
)
i_font_size
+=
(
i_value
*
i_font_size
)
/
10
;
{
else
if
(
i_value
<
-
5
)
int
i_value
=
atoi
(
value
);
if
(
(
i_value
>=
-
5
)
&&
(
i_value
<=
5
)
)
i_font_size
+=
(
i_value
*
i_font_size
)
/
10
;
else
if
(
i_value
<
-
5
)
i_font_size
=
-
i_value
;
i_font_size
=
-
i_value
;
else
if
(
i_value
>
5
)
else
if
(
i_value
>
5
)
i_font_size
=
i_value
;
i_font_size
=
i_value
;
}
}
else
else
i_font_size
=
atoi
(
value
);
i_font_size
=
atoi
(
value
);
}
}
else
if
(
!
strcasecmp
(
"color"
,
attr
)
&&
(
value
[
0
]
==
'#'
))
{
else
if
(
!
strcasecmp
(
"color"
,
attr
)
&&
(
value
[
0
]
==
'#'
)
)
i_font_color
=
strtol
(
value
+
1
,
NULL
,
16
);
{
i_font_color
=
strtol
(
value
+
1
,
NULL
,
16
);
i_font_color
&=
0x00ffffff
;
i_font_color
&=
0x00ffffff
;
}
}
else
if
(
!
strcasecmp
(
"alpha"
,
attr
)
&&
(
value
[
0
]
==
'#'
))
{
else
if
(
!
strcasecmp
(
"alpha"
,
attr
)
&&
(
value
[
0
]
==
'#'
)
)
i_font_alpha
=
strtol
(
value
+
1
,
NULL
,
16
);
{
i_font_alpha
=
strtol
(
value
+
1
,
NULL
,
16
);
i_font_alpha
&=
0xff
;
i_font_alpha
&=
0xff
;
}
}
}
}
rv
=
PushFont
(
p_fonts
,
rv
=
PushFont
(
p_fonts
,
psz_fontname
,
psz_fontname
,
i_font_size
,
i_font_size
,
(
i_font_color
&
0xffffff
)
|
((
i_font_alpha
&
0xff
)
<<
24
)
);
(
i_font_color
&
0xffffff
)
|
((
i_font_alpha
&
0xff
)
<<
24
)
);
free
(
psz_fontname
);
free
(
psz_fontname
);
return
rv
;
return
rv
;
}
}
static
void
setFontAttibutes
(
char
*
psz_fontname
,
int
i_font_size
,
uint32_t
i_font_color
,
static
void
setFontAttibutes
(
char
*
psz_fontname
,
int
i_font_size
,
uint32_t
i_font_color
,
bool
b_bold
,
bool
b_italic
,
bool
b_underline
,
bool
b_bold
,
bool
b_italic
,
bool
b_underline
,
CFRange
p_range
,
CFMutableAttributedStringRef
p_attrString
)
CFRange
p_range
,
CFMutableAttributedStringRef
p_attrString
)
{
{
CFStringRef
p_cfString
;
CFStringRef
p_cfString
;
CTFontRef
p_font
;
CTFontRef
p_font
;
// Handle font name and size
// Handle font name and size
p_cfString
=
CFStringCreateWithCString
(
NULL
,
p_cfString
=
CFStringCreateWithCString
(
NULL
,
psz_fontname
,
psz_fontname
,
kCFStringEncodingUTF8
);
kCFStringEncodingUTF8
);
p_font
=
CTFontCreateWithName
(
p_cfString
,
p_font
=
CTFontCreateWithName
(
p_cfString
,
(
float
)
i_font_size
,
(
float
)
i_font_size
,
NULL
);
NULL
);
CFRelease
(
p_cfString
);
CFRelease
(
p_cfString
);
CFAttributedStringSetAttribute
(
p_attrString
,
CFAttributedStringSetAttribute
(
p_attrString
,
p_range
,
p_range
,
kCTFontAttributeName
,
kCTFontAttributeName
,
p_font
);
p_font
);
CFRelease
(
p_font
);
CFRelease
(
p_font
);
// Handle Underline
// Handle Underline
SInt32
_uline
;
SInt32
_uline
;
if
(
b_underline
)
if
(
b_underline
)
_uline
=
kCTUnderlineStyleSingle
;
_uline
=
kCTUnderlineStyleSingle
;
else
else
_uline
=
kCTUnderlineStyleNone
;
_uline
=
kCTUnderlineStyleNone
;
CFNumberRef
underline
=
CFNumberCreate
(
NULL
,
kCFNumberSInt32Type
,
&
_uline
);
CFNumberRef
underline
=
CFNumberCreate
(
NULL
,
kCFNumberSInt32Type
,
&
_uline
);
CFAttributedStringSetAttribute
(
p_attrString
,
CFAttributedStringSetAttribute
(
p_attrString
,
p_range
,
p_range
,
kCTUnderlineStyleAttributeName
,
kCTUnderlineStyleAttributeName
,
underline
);
underline
);
CFRelease
(
underline
);
CFRelease
(
underline
);
// Handle Bold
// Handle Bold
float
_weight
;
float
_weight
;
if
(
b_bold
)
if
(
b_bold
)
_weight
=
0
.
5
;
_weight
=
0
.
5
;
else
else
_weight
=
0
.
0
;
_weight
=
0
.
0
;
CFNumberRef
weight
=
CFNumberCreate
(
NULL
,
kCFNumberFloatType
,
&
_weight
);
CFNumberRef
weight
=
CFNumberCreate
(
NULL
,
kCFNumberFloatType
,
&
_weight
);
CFAttributedStringSetAttribute
(
p_attrString
,
CFAttributedStringSetAttribute
(
p_attrString
,
p_range
,
p_range
,
kCTFontWeightTrait
,
kCTFontWeightTrait
,
weight
);
weight
);
CFRelease
(
weight
);
CFRelease
(
weight
);
// Handle Italic
// Handle Italic
float
_slant
;
float
_slant
;
if
(
b_italic
)
if
(
b_italic
)
_slant
=
1
.
0
;
_slant
=
1
.
0
;
else
else
_slant
=
0
.
0
;
_slant
=
0
.
0
;
CFNumberRef
slant
=
CFNumberCreate
(
NULL
,
kCFNumberFloatType
,
&
_slant
);
CFNumberRef
slant
=
CFNumberCreate
(
NULL
,
kCFNumberFloatType
,
&
_slant
);
CFAttributedStringSetAttribute
(
p_attrString
,
CFAttributedStringSetAttribute
(
p_attrString
,
p_range
,
p_range
,
kCTFontSlantTrait
,
kCTFontSlantTrait
,
slant
);
slant
);
CFRelease
(
slant
);
CFRelease
(
slant
);
// Handle foreground colour
// Handle foreground colour
CGColorSpaceRef
rgbColorSpace
=
CGColorSpaceCreateDeviceRGB
();
CGColorSpaceRef
rgbColorSpace
=
CGColorSpaceCreateDeviceRGB
();
CGFloat
components
[]
=
{
(
float
)((
i_font_color
&
0x00ff0000
)
>>
16
)
/
255
.
0
,
CGFloat
components
[]
=
{
(
float
)((
i_font_color
&
0x00ff0000
)
>>
16
)
/
255
.
0
,
(
float
)((
i_font_color
&
0x0000ff00
)
>>
8
)
/
255
.
0
,
(
float
)((
i_font_color
&
0x0000ff00
)
>>
8
)
/
255
.
0
,
(
float
)((
i_font_color
&
0x000000ff
)
)
/
255
.
0
,
(
float
)((
i_font_color
&
0x000000ff
))
/
255
.
0
,
(
float
)(
255
-
((
i_font_color
&
0xff000000
)
>>
24
))
/
255
.
0
};
(
float
)(
255
-
((
i_font_color
&
0xff000000
)
>>
24
))
/
255
.
0
};
CGColorRef
fg_text
=
CGColorCreate
(
rgbColorSpace
,
components
);
CGColorRef
fg_text
=
CGColorCreate
(
rgbColorSpace
,
components
);
CGColorSpaceRelease
(
rgbColorSpace
);
CGColorSpaceRelease
(
rgbColorSpace
);
CFAttributedStringSetAttribute
(
p_attrString
,
CFAttributedStringSetAttribute
(
p_attrString
,
p_range
,
p_range
,
kCTForegroundColorAttributeName
,
kCTForegroundColorAttributeName
,
fg_text
);
fg_text
);
CFRelease
(
fg_text
);
CFRelease
(
fg_text
);
}
}
static
void
GetAttrStrFromFontStack
(
font_stack_t
**
p_fonts
,
static
void
GetAttrStrFromFontStack
(
font_stack_t
**
p_fonts
,
bool
b_bold
,
bool
b_italic
,
bool
b_uline
,
bool
b_bold
,
bool
b_italic
,
bool
b_uline
,
CFRange
p_range
,
CFMutableAttributedStringRef
p_attrString
)
CFRange
p_range
,
CFMutableAttributedStringRef
p_attrString
)
{
{
char
*
psz_fontname
=
NULL
;
char
*
psz_fontname
=
NULL
;
int
i_font_size
=
0
;
int
i_font_size
=
0
;
uint32_t
i_font_color
=
0
;
uint32_t
i_font_color
=
0
;
if
(
VLC_SUCCESS
==
PeekFont
(
p_fonts
,
&
psz_fontname
,
&
i_font_size
,
if
(
VLC_SUCCESS
==
PeekFont
(
p_fonts
,
&
psz_fontname
,
&
i_font_size
,
&
i_font_color
))
&
i_font_color
))
{
{
setFontAttibutes
(
psz_fontname
,
setFontAttibutes
(
psz_fontname
,
i_font_size
,
i_font_size
,
i_font_color
,
i_font_color
,
b_bold
,
b_italic
,
b_uline
,
b_bold
,
b_italic
,
b_uline
,
p_range
,
p_range
,
p_attrString
);
p_attrString
);
}
}
}
}
static
int
ProcessNodes
(
filter_t
*
p_filter
,
static
int
ProcessNodes
(
filter_t
*
p_filter
,
xml_reader_t
*
p_xml_reader
,
xml_reader_t
*
p_xml_reader
,
text_style_t
*
p_font_style
,
text_style_t
*
p_font_style
,
CFMutableAttributedStringRef
p_attrString
)
CFMutableAttributedStringRef
p_attrString
)
{
{
int
rv
=
VLC_SUCCESS
;
int
rv
=
VLC_SUCCESS
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
...
@@ -657,67 +623,61 @@ static int ProcessNodes( filter_t *p_filter,
...
@@ -657,67 +623,61 @@ static int ProcessNodes( filter_t *p_filter,
bool
b_bold
=
false
;
bool
b_bold
=
false
;
bool
b_uline
=
false
;
bool
b_uline
=
false
;
if
(
p_font_style
)
if
(
p_font_style
)
{
{
rv
=
PushFont
(
&
p_fonts
,
rv
=
PushFont
(
&
p_fonts
,
p_font_style
->
psz_fontname
,
p_font_style
->
psz_fontname
,
p_font_style
->
i_font_size
,
p_font_style
->
i_font_size
,
(
p_font_style
->
i_font_color
&
0xffffff
)
|
(
p_font_style
->
i_font_color
&
0xffffff
)
|
((
p_font_style
->
i_font_alpha
&
0xff
)
<<
24
)
);
((
p_font_style
->
i_font_alpha
&
0xff
)
<<
24
));
if
(
p_font_style
->
i_style_flags
&
STYLE_BOLD
)
if
(
p_font_style
->
i_style_flags
&
STYLE_BOLD
)
b_bold
=
true
;
b_bold
=
true
;
if
(
p_font_style
->
i_style_flags
&
STYLE_ITALIC
)
if
(
p_font_style
->
i_style_flags
&
STYLE_ITALIC
)
b_italic
=
true
;
b_italic
=
true
;
if
(
p_font_style
->
i_style_flags
&
STYLE_UNDERLINE
)
if
(
p_font_style
->
i_style_flags
&
STYLE_UNDERLINE
)
b_uline
=
true
;
b_uline
=
true
;
}
}
else
{
else
rv
=
PushFont
(
&
p_fonts
,
{
rv
=
PushFont
(
&
p_fonts
,
p_sys
->
psz_font_name
,
p_sys
->
psz_font_name
,
p_sys
->
i_font_size
,
p_sys
->
i_font_size
,
p_sys
->
i_font_color
);
p_sys
->
i_font_color
);
}
}
if
(
rv
!=
VLC_SUCCESS
)
if
(
rv
!=
VLC_SUCCESS
)
return
rv
;
return
rv
;
while
(
(
type
=
xml_ReaderNextNode
(
p_xml_reader
,
&
node
)
)
>
0
)
while
((
type
=
xml_ReaderNextNode
(
p_xml_reader
,
&
node
))
>
0
)
{
{
switch
(
type
)
{
switch
(
type
)
{
case
XML_READER_ENDELEM
:
case
XML_READER_ENDELEM
:
if
(
!
strcasecmp
(
"font"
,
node
)
)
if
(
!
strcasecmp
(
"font"
,
node
)
)
PopFont
(
&
p_fonts
);
PopFont
(
&
p_fonts
);
else
if
(
!
strcasecmp
(
"b"
,
node
)
)
else
if
(
!
strcasecmp
(
"b"
,
node
)
)
b_bold
=
false
;
b_bold
=
false
;
else
if
(
!
strcasecmp
(
"i"
,
node
)
)
else
if
(
!
strcasecmp
(
"i"
,
node
)
)
b_italic
=
false
;
b_italic
=
false
;
else
if
(
!
strcasecmp
(
"u"
,
node
)
)
else
if
(
!
strcasecmp
(
"u"
,
node
)
)
b_uline
=
false
;
b_uline
=
false
;
break
;
break
;
case
XML_READER_STARTELEM
:
case
XML_READER_STARTELEM
:
if
(
!
strcasecmp
(
"font"
,
node
)
)
if
(
!
strcasecmp
(
"font"
,
node
)
)
rv
=
HandleFontAttributes
(
p_xml_reader
,
&
p_fonts
);
rv
=
HandleFontAttributes
(
p_xml_reader
,
&
p_fonts
);
else
if
(
!
strcasecmp
(
"b"
,
node
)
)
else
if
(
!
strcasecmp
(
"b"
,
node
)
)
b_bold
=
true
;
b_bold
=
true
;
else
if
(
!
strcasecmp
(
"i"
,
node
)
)
else
if
(
!
strcasecmp
(
"i"
,
node
)
)
b_italic
=
true
;
b_italic
=
true
;
else
if
(
!
strcasecmp
(
"u"
,
node
)
)
else
if
(
!
strcasecmp
(
"u"
,
node
)
)
b_uline
=
true
;
b_uline
=
true
;
else
if
(
!
strcasecmp
(
"br"
,
node
)
)
else
if
(
!
strcasecmp
(
"br"
,
node
))
{
{
CFMutableAttributedStringRef
p_attrnode
=
CFAttributedStringCreateMutable
(
kCFAllocatorDefault
,
0
);
CFMutableAttributedStringRef
p_attrnode
=
CFAttributedStringCreateMutable
(
kCFAllocatorDefault
,
0
);
CFAttributedStringReplaceString
(
p_attrnode
,
CFRangeMake
(
0
,
0
),
CFSTR
(
"
\n
"
)
);
CFAttributedStringReplaceString
(
p_attrnode
,
CFRangeMake
(
0
,
0
),
CFSTR
(
"
\n
"
)
);
GetAttrStrFromFontStack
(
&
p_fonts
,
b_bold
,
b_italic
,
b_uline
,
GetAttrStrFromFontStack
(
&
p_fonts
,
b_bold
,
b_italic
,
b_uline
,
CFRangeMake
(
0
,
1
),
CFRangeMake
(
0
,
1
),
p_attrnode
);
p_attrnode
);
CFAttributedStringReplaceAttributedString
(
p_attrString
,
CFAttributedStringReplaceAttributedString
(
p_attrString
,
CFRangeMake
(
CFAttributedStringGetLength
(
p_attrString
),
0
),
CFRangeMake
(
CFAttributedStringGetLength
(
p_attrString
),
0
),
p_attrnode
);
p_attrnode
);
CFRelease
(
p_attrnode
);
CFRelease
(
p_attrnode
);
}
}
break
;
break
;
case
XML_READER_TEXT
:
case
XML_READER_TEXT
:
...
@@ -726,176 +686,157 @@ static int ProcessNodes( filter_t *p_filter,
...
@@ -726,176 +686,157 @@ static int ProcessNodes( filter_t *p_filter,
int
len
;
int
len
;
// Turn any multiple-whitespaces into single spaces
// Turn any multiple-whitespaces into single spaces
char
*
dup
=
strdup
(
node
);
char
*
dup
=
strdup
(
node
);
if
(
!
dup
)
if
(
!
dup
)
break
;
break
;
char
*
s
=
strpbrk
(
dup
,
"
\t\r\n
"
);
char
*
s
=
strpbrk
(
dup
,
"
\t\r\n
"
);
while
(
s
)
while
(
s
)
{
{
int
i_whitespace
=
strspn
(
s
,
"
\t\r\n
"
);
int
i_whitespace
=
strspn
(
s
,
"
\t\r\n
"
);
if
(
i_whitespace
>
1
)
if
(
i_whitespace
>
1
)
memmove
(
&
s
[
1
],
memmove
(
&
s
[
1
],
&
s
[
i_whitespace
],
&
s
[
i_whitespace
],
strlen
(
s
)
-
i_whitespace
+
1
);
strlen
(
s
)
-
i_whitespace
+
1
);
*
s
++
=
' '
;
*
s
++
=
' '
;
s
=
strpbrk
(
s
,
"
\t\r\n
"
);
s
=
strpbrk
(
s
,
"
\t\r\n
"
);
}
}
CFMutableAttributedStringRef
p_attrnode
=
CFAttributedStringCreateMutable
(
kCFAllocatorDefault
,
0
);
CFMutableAttributedStringRef
p_attrnode
=
CFAttributedStringCreateMutable
(
kCFAllocatorDefault
,
0
);
p_cfString
=
CFStringCreateWithCString
(
NULL
,
dup
,
kCFStringEncodingUTF8
);
p_cfString
=
CFStringCreateWithCString
(
NULL
,
dup
,
kCFStringEncodingUTF8
);
CFAttributedStringReplaceString
(
p_attrnode
,
CFRangeMake
(
0
,
0
),
p_cfString
);
CFAttributedStringReplaceString
(
p_attrnode
,
CFRangeMake
(
0
,
0
),
p_cfString
);
CFRelease
(
p_cfString
);
CFRelease
(
p_cfString
);
len
=
CFAttributedStringGetLength
(
p_attrnode
);
len
=
CFAttributedStringGetLength
(
p_attrnode
);
GetAttrStrFromFontStack
(
&
p_fonts
,
b_bold
,
b_italic
,
b_uline
,
GetAttrStrFromFontStack
(
&
p_fonts
,
b_bold
,
b_italic
,
b_uline
,
CFRangeMake
(
0
,
len
),
CFRangeMake
(
0
,
len
),
p_attrnode
);
p_attrnode
);
CFAttributedStringReplaceAttributedString
(
p_attrString
,
CFAttributedStringReplaceAttributedString
(
p_attrString
,
CFRangeMake
(
CFAttributedStringGetLength
(
p_attrString
),
0
),
CFRangeMake
(
CFAttributedStringGetLength
(
p_attrString
),
0
),
p_attrnode
);
p_attrnode
);
CFRelease
(
p_attrnode
);
CFRelease
(
p_attrnode
);
free
(
dup
);
free
(
dup
);
break
;
break
;
}
}
}
}
}
}
while
(
VLC_SUCCESS
==
PopFont
(
&
p_fonts
)
);
while
(
VLC_SUCCESS
==
PopFont
(
&
p_fonts
)
);
return
rv
;
return
rv
;
}
}
static
int
RenderHtml
(
filter_t
*
p_filter
,
subpicture_region_t
*
p_region_out
,
static
int
RenderHtml
(
filter_t
*
p_filter
,
subpicture_region_t
*
p_region_out
,
subpicture_region_t
*
p_region_in
,
subpicture_region_t
*
p_region_in
,
const
vlc_fourcc_t
*
p_chroma_list
)
const
vlc_fourcc_t
*
p_chroma_list
)
{
{
int
rv
=
VLC_SUCCESS
;
int
rv
=
VLC_SUCCESS
;
stream_t
*
p_sub
=
NULL
;
stream_t
*
p_sub
=
NULL
;
xml_t
*
p_xml
=
NULL
;
xml_t
*
p_xml
=
NULL
;
xml_reader_t
*
p_xml_reader
=
NULL
;
xml_reader_t
*
p_xml_reader
=
NULL
;
if
(
!
p_region_in
||
!
p_region_in
->
psz_html
)
if
(
!
p_region_in
||
!
p_region_in
->
psz_html
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
/* Reset the default fontsize in case screen metrics have changed */
/* Reset the default fontsize in case screen metrics have changed */
p_filter
->
p_sys
->
i_font_size
=
GetFontSize
(
p_filter
);
p_filter
->
p_sys
->
i_font_size
=
GetFontSize
(
p_filter
);
p_sub
=
stream_MemoryNew
(
VLC_OBJECT
(
p_filter
),
p_sub
=
stream_MemoryNew
(
VLC_OBJECT
(
p_filter
),
(
uint8_t
*
)
p_region_in
->
psz_html
,
(
uint8_t
*
)
p_region_in
->
psz_html
,
strlen
(
p_region_in
->
psz_html
),
strlen
(
p_region_in
->
psz_html
),
true
);
true
);
if
(
p_sub
)
if
(
p_sub
)
{
{
p_xml
=
xml_Create
(
p_filter
);
p_xml
=
xml_Create
(
p_filter
);
if
(
p_xml
)
{
if
(
p_xml
)
{
bool
b_karaoke
=
false
;
bool
b_karaoke
=
false
;
p_xml_reader
=
xml_ReaderCreate
(
p_xml
,
p_sub
);
p_xml_reader
=
xml_ReaderCreate
(
p_xml
,
p_sub
);
if
(
p_xml_reader
)
if
(
p_xml_reader
)
{
{
/* Look for Root Node */
/* Look for Root Node */
const
char
*
name
;
const
char
*
name
;
if
(
xml_ReaderNextNode
(
p_xml_reader
,
&
name
)
if
(
xml_ReaderNextNode
(
p_xml_reader
,
&
name
)
==
XML_READER_STARTELEM
)
==
XML_READER_STARTELEM
)
{
{
if
(
!
strcasecmp
(
"karaoke"
,
name
))
{
if
(
!
strcasecmp
(
"karaoke"
,
name
)
)
{
/* We're going to have to render the text a number
/* We're going to have to render the text a number
* of times to show the progress marker on the text.
* of times to show the progress marker on the text.
*/
*/
var_SetBool
(
p_filter
,
"text-rerender"
,
true
);
var_SetBool
(
p_filter
,
"text-rerender"
,
true
);
b_karaoke
=
true
;
b_karaoke
=
true
;
}
}
else
if
(
!
strcasecmp
(
"text"
,
name
))
else
if
(
!
strcasecmp
(
"text"
,
name
)
)
{
b_karaoke
=
false
;
b_karaoke
=
false
;
}
else
{
else
{
/* Only text and karaoke tags are supported */
/* Only text and karaoke tags are supported */
msg_Dbg
(
p_filter
,
"Unsupported top-level tag "
msg_Dbg
(
p_filter
,
"Unsupported top-level tag "
"<%s> ignored."
,
name
);
"<%s> ignored."
,
name
);
rv
=
VLC_EGENERIC
;
rv
=
VLC_EGENERIC
;
}
}
}
}
else
{
else
msg_Err
(
p_filter
,
"Malformed HTML subtitle"
);
{
msg_Err
(
p_filter
,
"Malformed HTML subtitle"
);
rv
=
VLC_EGENERIC
;
rv
=
VLC_EGENERIC
;
}
}
if
(
rv
!=
VLC_SUCCESS
)
if
(
rv
!=
VLC_SUCCESS
)
{
{
xml_ReaderDelete
(
p_xml_reader
);
xml_ReaderDelete
(
p_xml_reader
);
p_xml_reader
=
NULL
;
p_xml_reader
=
NULL
;
}
}
}
}
if
(
p_xml_reader
)
if
(
p_xml_reader
)
{
{
int
i_len
;
int
i_len
;
CFMutableAttributedStringRef
p_attrString
=
CFAttributedStringCreateMutable
(
kCFAllocatorDefault
,
0
);
CFMutableAttributedStringRef
p_attrString
=
CFAttributedStringCreateMutable
(
kCFAllocatorDefault
,
0
);
rv
=
ProcessNodes
(
p_filter
,
p_xml_reader
,
rv
=
ProcessNodes
(
p_filter
,
p_xml_reader
,
p_region_in
->
p_style
,
p_attrString
);
p_region_in
->
p_style
,
p_attrString
);
i_len
=
CFAttributedStringGetLength
(
p_attrString
);
i_len
=
CFAttributedStringGetLength
(
p_attrString
);
p_region_out
->
i_x
=
p_region_in
->
i_x
;
p_region_out
->
i_x
=
p_region_in
->
i_x
;
p_region_out
->
i_y
=
p_region_in
->
i_y
;
p_region_out
->
i_y
=
p_region_in
->
i_y
;
if
((
rv
==
VLC_SUCCESS
)
&&
(
i_len
>
0
))
if
((
rv
==
VLC_SUCCESS
)
&&
(
i_len
>
0
))
{
RenderYUVA
(
p_filter
,
p_region_out
,
p_attrString
);
RenderYUVA
(
p_filter
,
p_region_out
,
p_attrString
);
}
CFRelease
(
p_attrString
);
CFRelease
(
p_attrString
);
xml_ReaderDelete
(
p_xml_reader
);
xml_ReaderDelete
(
p_xml_reader
);
}
}
xml_Delete
(
p_xml
);
xml_Delete
(
p_xml
);
}
}
stream_Delete
(
p_sub
);
stream_Delete
(
p_sub
);
}
}
return
rv
;
return
rv
;
}
}
static
CGContextRef
CreateOffScreenContext
(
int
i_width
,
int
i_height
,
static
CGContextRef
CreateOffScreenContext
(
int
i_width
,
int
i_height
,
offscreen_bitmap_t
**
pp_memory
,
CGColorSpaceRef
*
pp_colorSpace
)
offscreen_bitmap_t
**
pp_memory
,
CGColorSpaceRef
*
pp_colorSpace
)
{
{
offscreen_bitmap_t
*
p_bitmap
;
offscreen_bitmap_t
*
p_bitmap
;
CGContextRef
p_context
=
NULL
;
CGContextRef
p_context
=
NULL
;
p_bitmap
=
(
offscreen_bitmap_t
*
)
malloc
(
sizeof
(
offscreen_bitmap_t
));
p_bitmap
=
(
offscreen_bitmap_t
*
)
malloc
(
sizeof
(
offscreen_bitmap_t
));
if
(
p_bitmap
)
if
(
p_bitmap
)
{
{
p_bitmap
->
i_bitsPerChannel
=
8
;
p_bitmap
->
i_bitsPerChannel
=
8
;
p_bitmap
->
i_bitsPerPixel
=
4
*
p_bitmap
->
i_bitsPerChannel
;
// A,R,G,B
p_bitmap
->
i_bitsPerPixel
=
4
*
p_bitmap
->
i_bitsPerChannel
;
// A,R,G,B
p_bitmap
->
i_bytesPerPixel
=
p_bitmap
->
i_bitsPerPixel
/
8
;
p_bitmap
->
i_bytesPerPixel
=
p_bitmap
->
i_bitsPerPixel
/
8
;
p_bitmap
->
i_bytesPerRow
=
i_width
*
p_bitmap
->
i_bytesPerPixel
;
p_bitmap
->
i_bytesPerRow
=
i_width
*
p_bitmap
->
i_bytesPerPixel
;
p_bitmap
->
p_data
=
calloc
(
i_height
,
p_bitmap
->
i_bytesPerRow
);
p_bitmap
->
p_data
=
calloc
(
i_height
,
p_bitmap
->
i_bytesPerRow
);
*
pp_colorSpace
=
CGColorSpaceCreateDeviceRGB
();
*
pp_colorSpace
=
CGColorSpaceCreateDeviceRGB
();
if
(
p_bitmap
->
p_data
&&
*
pp_colorSpace
)
if
(
p_bitmap
->
p_data
&&
*
pp_colorSpace
)
{
p_context
=
CGBitmapContextCreate
(
p_bitmap
->
p_data
,
i_width
,
i_height
,
p_context
=
CGBitmapContextCreate
(
p_bitmap
->
p_data
,
i_width
,
i_height
,
p_bitmap
->
i_bitsPerChannel
,
p_bitmap
->
i_bytesPerRow
,
p_bitmap
->
i_bitsPerChannel
,
p_bitmap
->
i_bytesPerRow
,
*
pp_colorSpace
,
kCGImageAlphaPremultipliedFirst
);
*
pp_colorSpace
,
kCGImageAlphaPremultipliedFirst
);
}
if
(
p_context
)
if
(
p_context
)
{
{
if
(
CGContextSetAllowsAntialiasing
!=
NULL
)
if
(
CGContextSetAllowsAntialiasing
!=
NULL
)
CGContextSetAllowsAntialiasing
(
p_context
,
true
);
{
CGContextSetAllowsAntialiasing
(
p_context
,
true
);
}
}
}
*
pp_memory
=
p_bitmap
;
*
pp_memory
=
p_bitmap
;
}
}
...
@@ -903,43 +844,41 @@ static CGContextRef CreateOffScreenContext( int i_width, int i_height,
...
@@ -903,43 +844,41 @@ static CGContextRef CreateOffScreenContext( int i_width, int i_height,
return
p_context
;
return
p_context
;
}
}
static
offscreen_bitmap_t
*
Compose
(
int
i_text_align
,
static
offscreen_bitmap_t
*
Compose
(
int
i_text_align
,
CFMutableAttributedStringRef
p_attrString
,
CFMutableAttributedStringRef
p_attrString
,
unsigned
i_width
,
unsigned
i_width
,
unsigned
i_height
,
unsigned
i_height
,
unsigned
*
pi_textblock_height
)
unsigned
*
pi_textblock_height
)
{
{
offscreen_bitmap_t
*
p_offScreen
=
NULL
;
offscreen_bitmap_t
*
p_offScreen
=
NULL
;
CGColorSpaceRef
p_colorSpace
=
NULL
;
CGColorSpaceRef
p_colorSpace
=
NULL
;
CGContextRef
p_context
=
NULL
;
CGContextRef
p_context
=
NULL
;
p_context
=
CreateOffScreenContext
(
i_width
,
i_height
,
&
p_offScreen
,
&
p_colorSpace
);
p_context
=
CreateOffScreenContext
(
i_width
,
i_height
,
&
p_offScreen
,
&
p_colorSpace
);
*
pi_textblock_height
=
0
;
*
pi_textblock_height
=
0
;
if
(
p_context
)
if
(
p_context
)
{
{
float
horiz_flush
;
float
horiz_flush
;
CGContextSetTextMatrix
(
p_context
,
CGAffineTransformIdentity
);
CGContextSetTextMatrix
(
p_context
,
CGAffineTransformIdentity
);
if
(
i_text_align
==
SUBPICTURE_ALIGN_RIGHT
)
if
(
i_text_align
==
SUBPICTURE_ALIGN_RIGHT
)
horiz_flush
=
1
.
0
;
horiz_flush
=
1
.
0
;
else
if
(
i_text_align
!=
SUBPICTURE_ALIGN_LEFT
)
else
if
(
i_text_align
!=
SUBPICTURE_ALIGN_LEFT
)
horiz_flush
=
0
.
5
;
horiz_flush
=
0
.
5
;
else
else
horiz_flush
=
0
.
0
;
horiz_flush
=
0
.
0
;
// Create the framesetter with the attributed string.
// Create the framesetter with the attributed string.
CTFramesetterRef
framesetter
=
CTFramesetterCreateWithAttributedString
(
p_attrString
);
CTFramesetterRef
framesetter
=
CTFramesetterCreateWithAttributedString
(
p_attrString
);
if
(
framesetter
)
if
(
framesetter
)
{
{
CTFrameRef
frame
;
CTFrameRef
frame
;
CGMutablePathRef
p_path
=
CGPathCreateMutable
();
CGMutablePathRef
p_path
=
CGPathCreateMutable
();
CGRect
p_bounds
=
CGRectMake
(
(
float
)
HORIZONTAL_MARGIN
,
CGRect
p_bounds
=
CGRectMake
((
float
)
HORIZONTAL_MARGIN
,
(
float
)
VERTICAL_MARGIN
,
(
float
)
VERTICAL_MARGIN
,
(
float
)(
i_width
-
HORIZONTAL_MARGIN
*
2
),
(
float
)(
i_width
-
HORIZONTAL_MARGIN
*
2
),
(
float
)(
i_height
-
VERTICAL_MARGIN
*
2
));
(
float
)(
i_height
-
VERTICAL_MARGIN
*
2
));
CGPathAddRect
(
p_path
,
NULL
,
p_bounds
);
CGPathAddRect
(
p_path
,
NULL
,
p_bounds
);
// Create the frame and draw it into the graphics context
// Create the frame and draw it into the graphics context
frame
=
CTFramesetterCreateFrame
(
framesetter
,
CFRangeMake
(
0
,
0
),
p_path
,
NULL
);
frame
=
CTFramesetterCreateFrame
(
framesetter
,
CFRangeMake
(
0
,
0
),
p_path
,
NULL
);
...
@@ -947,18 +886,16 @@ static offscreen_bitmap_t *Compose( int i_text_align,
...
@@ -947,18 +886,16 @@ static offscreen_bitmap_t *Compose( int i_text_align,
CGPathRelease
(
p_path
);
CGPathRelease
(
p_path
);
// Set up black outlining of the text --
// Set up black outlining of the text --
CGContextSetRGBStrokeColor
(
p_context
,
0
,
0
,
0
,
0
.
5
);
CGContextSetRGBStrokeColor
(
p_context
,
0
,
0
,
0
,
0
.
5
);
CGContextSetTextDrawingMode
(
p_context
,
kCGTextFillStroke
);
CGContextSetTextDrawingMode
(
p_context
,
kCGTextFillStroke
);
if
(
frame
!=
NULL
)
if
(
frame
!=
NULL
)
{
{
CFArrayRef
lines
;
CFArrayRef
lines
;
CGPoint
penPosition
;
CGPoint
penPosition
;
lines
=
CTFrameGetLines
(
frame
);
lines
=
CTFrameGetLines
(
frame
);
penPosition
.
y
=
i_height
;
penPosition
.
y
=
i_height
;
for
(
int
i
=
0
;
i
<
CFArrayGetCount
(
lines
);
i
++
)
for
(
int
i
=
0
;
i
<
CFArrayGetCount
(
lines
);
i
++
)
{
{
CGFloat
ascent
,
descent
,
leading
;
CGFloat
ascent
,
descent
,
leading
;
CTLineRef
line
=
(
CTLineRef
)
CFArrayGetValueAtIndex
(
lines
,
i
);
CTLineRef
line
=
(
CTLineRef
)
CFArrayGetValueAtIndex
(
lines
,
i
);
...
@@ -967,13 +904,13 @@ static offscreen_bitmap_t *Compose( int i_text_align,
...
@@ -967,13 +904,13 @@ static offscreen_bitmap_t *Compose( int i_text_align,
// Set the outlining for this line to be dependant on the size of the line -
// Set the outlining for this line to be dependant on the size of the line -
// make it about 5% of the ascent, with a minimum at 1.0
// make it about 5% of the ascent, with a minimum at 1.0
float
f_thickness
=
ascent
*
0
.
05
;
float
f_thickness
=
ascent
*
0
.
05
;
CGContextSetLineWidth
(
p_context
,
((
f_thickness
>
1
.
0
)
?
1
.
0
:
f_thickness
));
CGContextSetLineWidth
(
p_context
,
((
f_thickness
>
1
.
0
)
?
1
.
0
:
f_thickness
));
double
penOffset
=
CTLineGetPenOffsetForFlush
(
line
,
horiz_flush
,
(
i_width
-
HORIZONTAL_MARGIN
*
2
));
double
penOffset
=
CTLineGetPenOffsetForFlush
(
line
,
horiz_flush
,
(
i_width
-
HORIZONTAL_MARGIN
*
2
));
penPosition
.
x
=
HORIZONTAL_MARGIN
+
penOffset
;
penPosition
.
x
=
HORIZONTAL_MARGIN
+
penOffset
;
penPosition
.
y
-=
ascent
;
penPosition
.
y
-=
ascent
;
CGContextSetTextPosition
(
p_context
,
penPosition
.
x
,
penPosition
.
y
);
CGContextSetTextPosition
(
p_context
,
penPosition
.
x
,
penPosition
.
y
);
CTLineDraw
(
line
,
p_context
);
CTLineDraw
(
line
,
p_context
);
penPosition
.
y
-=
descent
+
leading
;
penPosition
.
y
-=
descent
+
leading
;
}
}
...
@@ -983,21 +920,21 @@ static offscreen_bitmap_t *Compose( int i_text_align,
...
@@ -983,21 +920,21 @@ static offscreen_bitmap_t *Compose( int i_text_align,
}
}
CFRelease
(
framesetter
);
CFRelease
(
framesetter
);
}
}
CGContextFlush
(
p_context
);
CGContextFlush
(
p_context
);
CGContextRelease
(
p_context
);
CGContextRelease
(
p_context
);
}
}
if
(
p_colorSpace
)
CGColorSpaceRelease
(
p_colorSpace
);
if
(
p_colorSpace
)
CGColorSpaceRelease
(
p_colorSpace
);
return
p_offScreen
;
return
p_offScreen
;
}
}
static
int
GetFontSize
(
filter_t
*
p_filter
)
static
int
GetFontSize
(
filter_t
*
p_filter
)
{
{
return
p_filter
->
fmt_out
.
video
.
i_height
/
DEFAULT_REL_FONT_SIZE
;
return
p_filter
->
fmt_out
.
video
.
i_height
/
DEFAULT_REL_FONT_SIZE
;
}
}
static
int
RenderYUVA
(
filter_t
*
p_filter
,
subpicture_region_t
*
p_region
,
static
int
RenderYUVA
(
filter_t
*
p_filter
,
subpicture_region_t
*
p_region
,
CFMutableAttributedStringRef
p_attrString
)
CFMutableAttributedStringRef
p_attrString
)
{
{
offscreen_bitmap_t
*
p_offScreen
=
NULL
;
offscreen_bitmap_t
*
p_offScreen
=
NULL
;
unsigned
i_textblock_height
=
0
;
unsigned
i_textblock_height
=
0
;
...
@@ -1006,38 +943,36 @@ static int RenderYUVA( filter_t *p_filter, subpicture_region_t *p_region,
...
@@ -1006,38 +943,36 @@ static int RenderYUVA( filter_t *p_filter, subpicture_region_t *p_region,
unsigned
i_height
=
p_filter
->
fmt_out
.
video
.
i_visible_height
;
unsigned
i_height
=
p_filter
->
fmt_out
.
video
.
i_visible_height
;
unsigned
i_text_align
=
p_region
->
i_align
&
0x3
;
unsigned
i_text_align
=
p_region
->
i_align
&
0x3
;
if
(
!
p_attrString
)
if
(
!
p_attrString
)
{
{
msg_Err
(
p_filter
,
"Invalid argument to RenderYUVA"
);
msg_Err
(
p_filter
,
"Invalid argument to RenderYUVA"
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
p_offScreen
=
Compose
(
i_text_align
,
p_attrString
,
p_offScreen
=
Compose
(
i_text_align
,
p_attrString
,
i_width
,
i_height
,
&
i_textblock_height
);
i_width
,
i_height
,
&
i_textblock_height
);
if
(
!
p_offScreen
)
if
(
!
p_offScreen
)
{
{
msg_Err
(
p_filter
,
"No offscreen buffer"
);
msg_Err
(
p_filter
,
"No offscreen buffer"
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
uint8_t
*
p_dst_y
,
*
p_dst_u
,
*
p_dst_v
,
*
p_dst_a
;
uint8_t
*
p_dst_y
,
*
p_dst_u
,
*
p_dst_v
,
*
p_dst_a
;
video_format_t
fmt
;
video_format_t
fmt
;
int
i_offset
;
int
i_offset
;
unsigned
x
,
y
,
i_pitch
;
unsigned
i_pitch
;
uint8_t
i_y
,
i_u
,
i_v
;
// YUV values, derived from incoming RGB
uint8_t
i_y
,
i_u
,
i_v
;
// YUV values, derived from incoming RGB
// Create a new subpicture region
// Create a new subpicture region
memset
(
&
fmt
,
0
,
sizeof
(
video_format_t
)
);
memset
(
&
fmt
,
0
,
sizeof
(
video_format_t
)
);
fmt
.
i_chroma
=
VLC_CODEC_YUVA
;
fmt
.
i_chroma
=
VLC_CODEC_YUVA
;
fmt
.
i_width
=
fmt
.
i_visible_width
=
i_width
;
fmt
.
i_width
=
fmt
.
i_visible_width
=
i_width
;
fmt
.
i_height
=
fmt
.
i_visible_height
=
__MIN
(
i_height
,
i_textblock_height
+
VERTICAL_MARGIN
*
2
);
fmt
.
i_height
=
fmt
.
i_visible_height
=
__MIN
(
i_height
,
i_textblock_height
+
VERTICAL_MARGIN
*
2
);
fmt
.
i_x_offset
=
fmt
.
i_y_offset
=
0
;
fmt
.
i_x_offset
=
fmt
.
i_y_offset
=
0
;
fmt
.
i_sar_num
=
1
;
fmt
.
i_sar_num
=
1
;
fmt
.
i_sar_den
=
1
;
fmt
.
i_sar_den
=
1
;
p_region
->
p_picture
=
picture_NewFromFormat
(
&
fmt
);
p_region
->
p_picture
=
picture_NewFromFormat
(
&
fmt
);
if
(
!
p_region
->
p_picture
)
if
(
!
p_region
->
p_picture
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
p_region
->
fmt
=
fmt
;
p_region
->
fmt
=
fmt
;
...
@@ -1048,20 +983,18 @@ static int RenderYUVA( filter_t *p_filter, subpicture_region_t *p_region,
...
@@ -1048,20 +983,18 @@ static int RenderYUVA( filter_t *p_filter, subpicture_region_t *p_region,
i_pitch
=
p_region
->
p_picture
->
A_PITCH
;
i_pitch
=
p_region
->
p_picture
->
A_PITCH
;
i_offset
=
(
i_height
+
VERTICAL_MARGIN
<
fmt
.
i_height
)
?
VERTICAL_MARGIN
*
i_pitch
:
0
;
i_offset
=
(
i_height
+
VERTICAL_MARGIN
<
fmt
.
i_height
)
?
VERTICAL_MARGIN
*
i_pitch
:
0
;
for
(
y
=
0
;
y
<
fmt
.
i_height
;
y
++
)
for
(
unsigned
y
=
0
;
y
<
fmt
.
i_height
;
y
++
)
{
{
for
(
unsigned
x
=
0
;
x
<
fmt
.
i_width
;
x
++
)
{
for
(
x
=
0
;
x
<
fmt
.
i_width
;
x
++
)
{
int
i_alpha
=
p_offScreen
->
p_data
[
y
*
p_offScreen
->
i_bytesPerRow
+
x
*
p_offScreen
->
i_bytesPerPixel
];
int
i_alpha
=
p_offScreen
->
p_data
[
y
*
p_offScreen
->
i_bytesPerRow
+
x
*
p_offScreen
->
i_bytesPerPixel
];
int
i_red
=
p_offScreen
->
p_data
[
y
*
p_offScreen
->
i_bytesPerRow
+
x
*
p_offScreen
->
i_bytesPerPixel
+
1
];
int
i_red
=
p_offScreen
->
p_data
[
y
*
p_offScreen
->
i_bytesPerRow
+
x
*
p_offScreen
->
i_bytesPerPixel
+
1
];
int
i_green
=
p_offScreen
->
p_data
[
y
*
p_offScreen
->
i_bytesPerRow
+
x
*
p_offScreen
->
i_bytesPerPixel
+
2
];
int
i_green
=
p_offScreen
->
p_data
[
y
*
p_offScreen
->
i_bytesPerRow
+
x
*
p_offScreen
->
i_bytesPerPixel
+
2
];
int
i_blue
=
p_offScreen
->
p_data
[
y
*
p_offScreen
->
i_bytesPerRow
+
x
*
p_offScreen
->
i_bytesPerPixel
+
3
];
int
i_blue
=
p_offScreen
->
p_data
[
y
*
p_offScreen
->
i_bytesPerRow
+
x
*
p_offScreen
->
i_bytesPerPixel
+
3
];
i_y
=
(
uint8_t
)
__MIN
(
abs
(
2104
*
i_red
+
4130
*
i_green
+
i_y
=
(
uint8_t
)
__MIN
(
abs
(
2104
*
i_red
+
4130
*
i_green
+
802
*
i_blue
+
4096
+
131072
)
>>
13
,
235
);
802
*
i_blue
+
4096
+
131072
)
>>
13
,
235
);
i_u
=
(
uint8_t
)
__MIN
(
abs
(
-
1214
*
i_red
+
-
2384
*
i_green
+
i_u
=
(
uint8_t
)
__MIN
(
abs
(
-
1214
*
i_red
+
-
2384
*
i_green
+
3598
*
i_blue
+
4096
+
1048576
)
>>
13
,
240
);
3598
*
i_blue
+
4096
+
1048576
)
>>
13
,
240
);
i_v
=
(
uint8_t
)
__MIN
(
abs
(
3598
*
i_red
+
-
3013
*
i_green
+
i_v
=
(
uint8_t
)
__MIN
(
abs
(
3598
*
i_red
+
-
3013
*
i_green
+
-
585
*
i_blue
+
4096
+
1048576
)
>>
13
,
240
);
-
585
*
i_blue
+
4096
+
1048576
)
>>
13
,
240
);
p_dst_y
[
i_offset
+
x
]
=
i_y
;
p_dst_y
[
i_offset
+
x
]
=
i_y
;
...
@@ -1072,8 +1005,8 @@ static int RenderYUVA( filter_t *p_filter, subpicture_region_t *p_region,
...
@@ -1072,8 +1005,8 @@ static int RenderYUVA( filter_t *p_filter, subpicture_region_t *p_region,
i_offset
+=
i_pitch
;
i_offset
+=
i_pitch
;
}
}
free
(
p_offScreen
->
p_data
);
free
(
p_offScreen
->
p_data
);
free
(
p_offScreen
);
free
(
p_offScreen
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment