summaryrefslogtreecommitdiffstats
path: root/libass/ass_bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'libass/ass_bitmap.c')
-rw-r--r--libass/ass_bitmap.c75
1 files changed, 67 insertions, 8 deletions
diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c
index cfaa16b..23b24ea 100644
--- a/libass/ass_bitmap.c
+++ b/libass/ass_bitmap.c
@@ -18,6 +18,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "config.h"
+
#include <stdlib.h>
#include <string.h>
#include <math.h>
@@ -156,7 +158,63 @@ Bitmap *copy_bitmap(const Bitmap *src)
return dst;
}
-Bitmap *outline_to_bitmap(ASS_Library *library, FT_Library ftlib,
+#if CONFIG_RASTERIZER
+
+Bitmap *outline_to_bitmap(ASS_Renderer *render_priv,
+ FT_Outline *outline, int bord)
+{
+ ASS_Rasterizer *rst = &render_priv->rasterizer;
+ if (!rasterizer_set_outline(rst, outline)) {
+ ass_msg(render_priv->library, MSGL_WARN, "Failed to process glyph outline!\n");
+ return NULL;
+ }
+
+ if (rst->x_min >= rst->x_max || rst->y_min >= rst->y_max) {
+ Bitmap *bm = alloc_bitmap(2 * bord, 2 * bord);
+ bm->left = bm->top = -bord;
+ return bm;
+ }
+
+ int x_min = rst->x_min >> 6;
+ int y_min = rst->y_min >> 6;
+ int x_max = (rst->x_max + 63) >> 6;
+ int y_max = (rst->y_max + 63) >> 6;
+ int w = x_max - x_min;
+ int h = y_max - y_min;
+
+ if (w * h > 8000000) {
+ ass_msg(render_priv->library, MSGL_WARN, "Glyph bounding box too large: %dx%dpx",
+ w, h);
+ return NULL;
+ }
+
+ int mask = (1 << rst->tile_order) - 1;
+ int tile_w = (w + 2 * bord + mask) & ~mask;
+ int tile_h = (h + 2 * bord + mask) & ~mask;
+ Bitmap *bm = alloc_bitmap(tile_w, tile_h);
+ bm->left = x_min - bord;
+ bm->top = -y_max - bord;
+
+ int offs = bord & ~mask;
+ int bord_h = tile_h - h - bord;
+ if (!rasterizer_fill(rst,
+ bm->buffer + offs * (bm->stride + 1),
+ x_min - bord + offs,
+ y_min - bord_h + (bord_h & ~mask),
+ ((w + bord + mask) & ~mask) - offs,
+ ((h + bord + mask) & ~mask) - offs,
+ bm->stride, 1)) {
+ ass_msg(render_priv->library, MSGL_WARN, "Failed to rasterize glyph!\n");
+ ass_free_bitmap(bm);
+ return NULL;
+ }
+
+ return bm;
+}
+
+#else
+
+Bitmap *outline_to_bitmap(ASS_Renderer *render_priv,
FT_Outline *outline, int bord)
{
Bitmap *bm;
@@ -186,7 +244,7 @@ Bitmap *outline_to_bitmap(ASS_Library *library, FT_Library ftlib,
bbox.yMax >>= 6;
if (w * h > 8000000) {
- ass_msg(library, MSGL_WARN, "Glyph bounding box too large: %dx%dpx",
+ ass_msg(render_priv->library, MSGL_WARN, "Glyph bounding box too large: %dx%dpx",
w, h);
return NULL;
}
@@ -203,8 +261,8 @@ Bitmap *outline_to_bitmap(ASS_Library *library, FT_Library ftlib,
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
// render into target bitmap
- if ((error = FT_Outline_Get_Bitmap(ftlib, outline, &bitmap))) {
- ass_msg(library, MSGL_WARN, "Failed to rasterize glyph: %d\n", error);
+ if ((error = FT_Outline_Get_Bitmap(render_priv->ftlibrary, outline, &bitmap))) {
+ ass_msg(render_priv->library, MSGL_WARN, "Failed to rasterize glyph: %d\n", error);
ass_free_bitmap(bm);
return NULL;
}
@@ -212,6 +270,8 @@ Bitmap *outline_to_bitmap(ASS_Library *library, FT_Library ftlib,
return bm;
}
+#endif
+
/**
* \brief fix outline bitmap
*
@@ -495,8 +555,7 @@ void be_blur_c(uint8_t *buf, intptr_t w,
}
}
-int outline_to_bitmap3(ASS_Library *library, ASS_SynthPriv *priv_blur,
- FT_Library ftlib, FT_Outline *outline, FT_Outline *border,
+int outline_to_bitmap3(ASS_Renderer *render_priv, FT_Outline *outline, FT_Outline *border,
Bitmap **bm_g, Bitmap **bm_o, Bitmap **bm_s,
int be, double blur_radius, FT_Vector shadow_offset,
int border_style, int border_visible)
@@ -513,12 +572,12 @@ int outline_to_bitmap3(ASS_Library *library, ASS_SynthPriv *priv_blur,
*bm_g = *bm_o = *bm_s = 0;
if (outline)
- *bm_g = outline_to_bitmap(library, ftlib, outline, bord);
+ *bm_g = outline_to_bitmap(render_priv, outline, bord);
if (!*bm_g)
return 1;
if (border) {
- *bm_o = outline_to_bitmap(library, ftlib, border, bord);
+ *bm_o = outline_to_bitmap(render_priv, border, bord);
if (!*bm_o) {
return 1;
}