return bm_s;
}
+/**
+ * \brief Shift a bitmap by the fraction of a pixel in x and y direction
+ * expressed in 26.6 fixed point
+ */
+static void shift_bitmap(unsigned char *buf, int w, int h, int shift_x,
+ int shift_y)
+{
+ int x, y, b;
+
+ // Shift in x direction
+ if (shift_x > 0) {
+ for (y = 0; y < h; y++) {
+ for (x = w - 1; x > 0; x--) {
+ b = (buf[x + y * w - 1] * shift_x) / 64;
+ buf[x + y * w - 1] -= b;
+ buf[x + y * w] += b;
+ }
+ }
+ } else if (shift_x < 0) {
+ shift_x = -shift_x;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w - 1; x++) {
+ b = (buf[x + y * w + 1] * shift_x) / 64;
+ buf[x + y * w + 1] -= b;
+ buf[x + y * w] += b;
+ }
+ }
+ }
+
+ // Shift in y direction
+ if (shift_y > 0) {
+ for (x = 0; x < w; x++) {
+ for (y = h - 1; y > 0; y--) {
+ b = (buf[x + (y - 1) * w] * shift_y) / 64;
+ buf[x + (y - 1) * w] -= b;
+ buf[x + y * w] += b;
+ }
+ }
+ } else if (shift_y < 0) {
+ shift_y = -shift_y;
+ for (x = 0; x < w; x++) {
+ for (y = 0; y < h - 1; y++) {
+ b = (buf[x + (y + 1) * w] * shift_y) / 64;
+ buf[x + (y + 1) * w] -= b;
+ buf[x + y * w] += b;
+ }
+ }
+ }
+}
+
/**
* \brief Blur with [[1,2,1]. [2,4,2], [1,2,1]] kernel
* This blur is the same as the one employed by vsfilter.
int glyph_to_bitmap(ass_synth_priv_t *priv_blur,
FT_Glyph glyph, FT_Glyph outline_glyph,
bitmap_t **bm_g, bitmap_t **bm_o, bitmap_t **bm_s,
- int be, double blur_radius)
+ int be, double blur_radius, FT_Vector shadow_offset)
{
int bord = be ? (be / 4 + 1) : 0;
blur_radius *= 2;
bord = (blur_radius > 0.0) ? blur_radius + 1 : bord;
+ if (bord == 0 && (shadow_offset.x || shadow_offset.y))
+ bord = 1;
assert(bm_g && bm_o && bm_s);
else
*bm_s = copy_bitmap(*bm_g);
+ shift_bitmap((*bm_s)->buffer, (*bm_s)->w,(*bm_s)->h,
+ shadow_offset.x, shadow_offset.y);
+
assert(bm_s);
return 0;
}
#define MAX_LINES_INITIAL 64
#define BLUR_MAX_RADIUS 100.0
#define MAX_BE 100
-#define ROUND(x) ((int) ((x) + .5))
#define SUBPIXEL_MASK 63 // d6 bitmask for subpixel accuracy adjustment
static int last_render_id = 0;
pen_x =
dst_x + (info->pos.x >> 6) +
- ROUND(info->shadow_x * render_priv->border_scale);
+ (int) (info->shadow_x * render_priv->border_scale);
pen_y =
dst_y + (info->pos.y >> 6) +
- ROUND(info->shadow_y * render_priv->border_scale);
+ (int) (info->shadow_y * render_priv->border_scale);
bm = info->bm_s;
here_tail = tail;
info->glyph, info->outline_glyph,
&info->bm, &info->bm_o,
&info->bm_s, info->be,
- info->blur * render_priv->border_scale);
+ info->blur * render_priv->border_scale,
+ info->hash_key.shadow_offset);
if (error)
info->symbol = 0;
render_priv->state.be;
text_info->glyphs[text_info->length].hash_key.blur =
render_priv->state.blur;
+ text_info->glyphs[text_info->length].hash_key.shadow_offset.x =
+ double_to_d6(
+ render_priv->state.shadow_x * render_priv->border_scale -
+ (int) (render_priv->state.shadow_x *
+ render_priv->border_scale));
+ text_info->glyphs[text_info->length].hash_key.shadow_offset.y =
+ double_to_d6(
+ render_priv->state.shadow_y * render_priv->border_scale -
+ (int) (render_priv->state.shadow_y *
+ render_priv->border_scale));
text_info->length++;