}
static bool quantize_transform(double m[3][3], ASS_Vector *pos,
+ ASS_DVector *offset, bool first,
BitmapHashKey *key)
{
// Full transform:
for (int j = 0; j < 2; j++)
m[i][j] -= m[2][j] * center[i];
- int32_t qr[2];
+ double delta[2] = {0};
+ if (!first) {
+ delta[0] = offset->x;
+ delta[1] = offset->y;
+ }
+
+ int32_t qr[2]; // quantized center position
for (int i = 0; i < 2; i++) {
center[i] /= 64 >> SUBPIXEL_ORDER;
+ center[i] -= delta[i];
if (!(fabs(center[i]) < max_val))
return false;
qr[i] = lrint(center[i]);
qm[2][j] = lrint(val);
}
+ if (first && offset) {
+ offset->x = center[0] - qr[0];
+ offset->y = center[1] - qr[1];
+ }
pos->x = qr[0] >> SUBPIXEL_ORDER;
pos->y = qr[1] >> SUBPIXEL_ORDER;
key->offset.x = qr[0] & ((1 << SUBPIXEL_ORDER) - 1);
ASS_Vector pos;
BitmapHashKey key;
key.outline = ass_cache_get(render_priv->cache.outline_cache, &ol_key, render_priv);
- if (!key.outline || !key.outline->valid || !quantize_transform(m, &pos, &key)) {
+ if (!key.outline || !key.outline->valid ||
+ !quantize_transform(m, &pos, NULL, true, &key)) {
ass_cache_dec_ref(key.outline);
return;
}
*/
static void
get_bitmap_glyph(ASS_Renderer *render_priv, GlyphInfo *info,
- ASS_Vector *pos, ASS_Vector *pos_o, int flags)
+ ASS_Vector *pos, ASS_Vector *pos_o,
+ ASS_DVector *offset, bool first, int flags)
{
if (!info->outline || info->symbol == '\n' || info->symbol == 0 || info->skip) {
ass_cache_dec_ref(info->outline);
BitmapHashKey key;
key.outline = info->outline;
- if (!quantize_transform(m, pos, &key)) {
+ if (!quantize_transform(m, pos, offset, first, &key)) {
ass_cache_dec_ref(info->outline);
return;
}
}
key.outline = ass_cache_get(render_priv->cache.outline_cache, &ol_key, render_priv);
- if (!key.outline || !key.outline->valid || !quantize_transform(m, pos_o, &key)) {
+ if (!key.outline || !key.outline->valid ||
+ !quantize_transform(m, pos_o, offset, false, &key)) {
ass_cache_dec_ref(key.outline);
return;
}
CombinedBitmapInfo *combined_info = text_info->combined_bitmaps;
CombinedBitmapInfo *current_info = NULL;
GlyphInfo *last_info = NULL;
+ ASS_DVector offset;
for (int i = 0; i < text_info->length; i++) {
GlyphInfo *info = text_info->glyphs + i;
if (info->linebreak) linebreak = 1;
if (flags == FILTER_NONZERO_SHADOW && (info->c[0] & 0xFF) == 0xFF)
flags = 0;
- ASS_Vector pos, pos_o;
- info->pos.x = double_to_d6(device_x + d6_to_double(info->pos.x) * render_priv->font_scale_x);
- info->pos.y = double_to_d6(device_y) + info->pos.y;
- get_bitmap_glyph(render_priv, info, &pos, &pos_o, flags);
-
if (linebreak || is_new_bm_run(info, last_info)) {
linebreak = 0;
last_info = NULL;
if (nb_bitmaps >= text_info->max_bitmaps) {
size_t new_size = 2 * text_info->max_bitmaps;
if (!ASS_REALLOC_ARRAY(text_info->combined_bitmaps, new_size)) {
- ass_cache_dec_ref(info->bm);
- ass_cache_dec_ref(info->bm_o);
+ ass_cache_dec_ref(info->outline);
continue;
}
text_info->max_bitmaps = new_size;
current_info->bitmap_count = current_info->max_bitmap_count = 0;
current_info->bitmaps = malloc(MAX_SUB_BITMAPS_INITIAL * sizeof(BitmapRef));
if (!current_info->bitmaps) {
- ass_cache_dec_ref(info->bm);
- ass_cache_dec_ref(info->bm_o);
+ ass_cache_dec_ref(info->outline);
continue;
}
current_info->max_bitmap_count = MAX_SUB_BITMAPS_INITIAL;
}
last_info = info;
+ ASS_Vector pos, pos_o;
+ info->pos.x = double_to_d6(device_x + d6_to_double(info->pos.x) * render_priv->font_scale_x);
+ info->pos.y = double_to_d6(device_y) + info->pos.y;
+ get_bitmap_glyph(render_priv, info, &pos, &pos_o,
+ &offset, !current_info->bitmap_count, flags);
+
if (!current_info || (!info->bm && !info->bm_o)) {
ass_cache_dec_ref(info->bm);
ass_cache_dec_ref(info->bm_o);