quartztext: support kerning and some text attributes
authorNaohiro KORIYAMA <nkoriyama@gmail.com>
Sat, 23 Jun 2012 17:55:15 +0000 (02:55 +0900)
committerFrancois Cartegnie <fcvlcdev@free.fr>
Thu, 14 Aug 2014 08:44:25 +0000 (17:44 +0900)
Signed-off-by: Francois Cartegnie <fcvlcdev@free.fr>
modules/text_renderer/quartztext.c

index ceb97a6..93748a7 100644 (file)
@@ -80,6 +80,7 @@ static int RenderYUVA(filter_t *p_filter, subpicture_region_t *p_region,
 
 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_halfwidth,
+                              int i_spacing,
                               CFRange p_range, CFMutableAttributedStringRef p_attrString);
 
 /*****************************************************************************
@@ -100,6 +101,8 @@ static void setFontAttibutes(char *psz_fontname, int i_font_size, uint32_t i_fon
     "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,"\
     " #00FF00 = green, #FFFF00 = yellow (red + green), #FFFFFF = white")
+#define OUTLINE_TEXT N_("Add outline")
+#define SHADOW_TEXT N_("Add shadow")
 
 static const int pi_color_values[] = {
   0x00000000, 0x00808080, 0x00C0C0C0, 0x00FFFFFF, 0x00800000,
@@ -134,6 +137,8 @@ vlc_module_begin ()
     add_integer("quartztext-color", 0x00FFFFFF, COLOR_TEXT,
                  COLOR_LONGTEXT, false)
         change_integer_list(pi_color_values, ppsz_color_descriptions)
+    add_bool("quartztext-outline", false, OUTLINE_TEXT, NULL, false)
+    add_bool("quartztext-shadow", true, SHADOW_TEXT, NULL, false)
     set_capability("text renderer", 50)
     add_shortcut("text")
     set_callbacks(Create, Destroy)
@@ -181,6 +186,8 @@ struct filter_sys_t
     uint8_t        i_font_opacity;
     int            i_font_color;
     int            i_font_size;
+    bool           b_outline;
+    bool           b_shadow;
 
 #ifndef TARGET_OS_IPHONE
     ATSFontContainerRef    *p_fonts;
@@ -205,6 +212,8 @@ static int Create(vlc_object_t *p_this)
     p_sys->psz_font_name  = var_CreateGetString(p_this, "quartztext-font");
     p_sys->i_font_opacity = 255;
     p_sys->i_font_color = VLC_CLIP(var_CreateGetInteger(p_this, "quartztext-color") , 0, 0xFFFFFF);
+    p_sys->b_outline = var_InheritBool(p_this, "quartztext-outline");
+    p_sys->b_shadow = var_InheritBool(p_this, "quartztext-shadow");
     p_sys->i_font_size = GetFontSize(p_filter);
 
     p_filter->pf_render_text = RenderText;
@@ -311,6 +320,7 @@ static int RenderText(filter_t *p_filter, subpicture_region_t *p_region_out,
     filter_sys_t *p_sys = p_filter->p_sys;
     char         *psz_string;
     int           i_font_size;
+    int           i_spacing = 0;
     uint32_t      i_font_color;
     bool          b_bold, b_uline, b_italic, b_halfwidth;
     vlc_value_t val;
@@ -340,6 +350,7 @@ static int RenderText(filter_t *p_filter, subpicture_region_t *p_region_out,
             if (p_region_in->p_style->i_style_flags & STYLE_HALFWIDTH)
                 b_halfwidth = TRUE;
         }
+        i_spacing = VLC_CLIP(p_region_in->p_style->i_spacing, 0, 255);
     } else {
         i_font_color = p_sys->i_font_color;
         i_font_size  = p_sys->i_font_size;
@@ -369,6 +380,7 @@ static int RenderText(filter_t *p_filter, subpicture_region_t *p_region_out,
         len = CFAttributedStringGetLength(p_attrString);
 
         setFontAttibutes(p_sys->psz_font_name, i_font_size, i_font_color, b_bold, b_italic, b_uline, b_halfwidth,
+                                             i_spacing,
                                              CFRangeMake(0, len), p_attrString);
 
         RenderYUVA(p_filter, p_region_out, p_attrString);
@@ -526,6 +538,7 @@ static int HandleFontAttributes(xml_reader_t *p_xml_reader,
 
 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_halfwidth,
+        int i_spacing,
         CFRange p_range, CFMutableAttributedStringRef p_attrString)
 {
     CFStringRef p_cfString;
@@ -613,6 +626,18 @@ static void setFontAttibutes(char *psz_fontname, int i_font_size, uint32_t i_fon
                                     fg_text);
     CFRelease(fg_text);
 
+    // spacing
+    if (i_spacing > 0)
+    {
+        CGFloat spacing = i_spacing;
+        CFNumberRef spacingCFNum = CFNumberCreate(NULL,
+                kCFNumberCGFloatType, &spacing);
+        CFAttributedStringSetAttribute(p_attrString,
+                                        p_range,
+                                        kCTKernAttributeName,
+                                        spacingCFNum);
+        CFRelease(spacingCFNum);
+    }
 }
 
 static void GetAttrStrFromFontStack(font_stack_t **p_fonts,
@@ -629,6 +654,7 @@ static void GetAttrStrFromFontStack(font_stack_t **p_fonts,
                          i_font_size,
                          i_font_color,
                          b_bold, b_italic, b_uline, FALSE,
+                         0,
                          p_range,
                          p_attrString);
     }
@@ -867,12 +893,14 @@ static CGContextRef CreateOffScreenContext(int i_width, int i_height,
     return p_context;
 }
 
-static offscreen_bitmap_t *Compose( subpicture_region_t *p_region,
+static offscreen_bitmap_t *Compose(filter_t *p_filter,
+                                    subpicture_region_t *p_region,
                                     CFMutableAttributedStringRef p_attrString,
                                     unsigned i_width,
                                     unsigned i_height,
                                     unsigned *pi_textblock_height)
 {
+    filter_sys_t *p_sys   = p_filter->p_sys;
     offscreen_bitmap_t  *p_offScreen  = NULL;
     CGColorSpaceRef      p_colorSpace = NULL;
     CGContextRef         p_context = NULL;
@@ -909,8 +937,19 @@ static offscreen_bitmap_t *Compose( subpicture_region_t *p_region,
             CGPathRelease(p_path);
 
             // Set up black outlining of the text --
-            CGContextSetRGBStrokeColor(p_context, 0, 0, 0, 0.5);
-            CGContextSetTextDrawingMode(p_context, kCGTextFillStroke);
+            if (p_sys->b_outline)
+            {
+                CGContextSetRGBStrokeColor(p_context, 0, 0, 0, 0.5);
+                CGContextSetTextDrawingMode(p_context, kCGTextFillStroke);
+            }
+
+            // Shadow
+            if (p_sys->b_shadow)
+            {
+                // TODO: Use CGContextSetShadowWithColor.
+                // TODO: Use user defined parrameters (color, distance, etc.)
+                CGContextSetShadow(p_context, CGSizeMake(3.0f, -3.0f), 2.0f);
+            }
 
             if (frame != NULL) {
                 CFArrayRef lines;
@@ -983,7 +1022,7 @@ static int RenderYUVA(filter_t *p_filter, subpicture_region_t *p_region,
         return VLC_EGENERIC;
     }
 
-    p_offScreen = Compose( p_region, p_attrString,
+    p_offScreen = Compose(p_filter, p_region, p_attrString,
                            i_width, i_height, &i_textblock_height);
 
     if (!p_offScreen) {