if (bord < 0 || bord > INT_MAX / 2)
return NULL;
- if (rst->x_max > INT_MAX - 63 || rst->y_max > INT_MAX - 63)
+ if (rst->bbox.x_max > INT_MAX - 63 || rst->bbox.y_max > INT_MAX - 63)
return NULL;
- 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 x_min = rst->bbox.x_min >> 6;
+ int y_min = rst->bbox.y_min >> 6;
+ int x_max = (rst->bbox.x_max + 63) >> 6;
+ int y_max = (rst->bbox.y_max + 63) >> 6;
int w = x_max - x_min;
int h = y_max - y_min;
}
}
-/*
- * \brief Update drawing cbox
- */
-static inline void update_cbox(ASS_Drawing *drawing, ASS_Vector *point)
-{
- ASS_Rect *box = &drawing->cbox;
-
- box->x_min = FFMIN(box->x_min, point->x);
- box->x_max = FFMAX(box->x_max, point->x);
- box->y_min = FFMIN(box->y_min, point->y);
- box->y_max = FFMAX(box->y_max, point->y);
-}
-
/*
* \brief Translate and scale a point coordinate according to baseline
* offset and scale.
*/
static inline void translate_point(ASS_Drawing *drawing, ASS_Vector *point)
{
- point->x = drawing->point_scale_x * point->x;
- point->y = drawing->point_scale_y * point->y;
+ point->x = lrint(drawing->point_scale_x * point->x);
+ point->y = lrint(drawing->point_scale_y * point->y);
- update_cbox(drawing, point);
+ rectangle_update(&drawing->cbox, point->x, point->y, point->x, point->y);
}
/*
ASS_Drawing *drawing = calloc(1, sizeof(*drawing));
if (!drawing)
return NULL;
- drawing->cbox.x_min = drawing->cbox.y_min = INT32_MAX;
- drawing->cbox.x_max = drawing->cbox.y_max = INT32_MIN;
+ rectangle_reset(&drawing->cbox);
drawing->library = lib;
drawing->scale_x = 1.;
drawing->scale_y = 1.;
#include <stdbool.h>
#include <stdint.h>
+#include "ass_utils.h"
+
typedef struct {
int32_t x, y;
double x_min, y_min, x_max, y_max;
} ASS_DRect;
+static inline void rectangle_reset(ASS_Rect *rect)
+{
+ rect->x_min = rect->y_min = INT32_MAX;
+ rect->x_max = rect->y_max = INT32_MIN;
+}
+
+static inline void rectangle_update(ASS_Rect *rect,
+ int32_t x_min, int32_t y_min, int32_t x_max, int32_t y_max)
+{
+ rect->x_min = FFMIN(rect->x_min, x_min);
+ rect->y_min = FFMIN(rect->y_min, y_min);
+ rect->x_max = FFMAX(rect->x_max, x_max);
+ rect->y_max = FFMAX(rect->y_max, y_max);
+}
+
/*
* Outline represented with array of points and array of segments.
* Segment here is spline of order 1 (line), 2 (quadratic) or 3 (cubic).
const ASS_Outline *path, bool extra)
{
if (!extra) {
- rst->x_min = rst->y_min = INT32_MAX;
- rst->x_max = rst->y_max = INT32_MIN;
+ rectangle_reset(&rst->bbox);
rst->n_first = 0;
}
rst->size[0] = rst->n_first;
assert(start == cur && cur == path->points + path->n_points);
for (size_t k = rst->n_first; k < rst->size[0]; k++) {
- rst->x_min = FFMIN(rst->x_min, rst->linebuf[0][k].x_min);
- rst->x_max = FFMAX(rst->x_max, rst->linebuf[0][k].x_max);
- rst->y_min = FFMIN(rst->y_min, rst->linebuf[0][k].y_min);
- rst->y_max = FFMAX(rst->y_max, rst->linebuf[0][k].y_max);
+ struct segment *line = &rst->linebuf[0][k];
+ rectangle_update(&rst->bbox,
+ line->x_min, line->y_min,
+ line->x_max, line->y_max);
}
if (!extra)
rst->n_first = rst->size[0];
line->y_max -= y0;
line->c -= line->a * (int64_t) x0 + line->b * (int64_t) y0;
}
- rst->x_min -= x0;
- rst->x_max -= x0;
- rst->y_min -= y0;
- rst->y_max -= y0;
+ rst->bbox.x_min -= x0;
+ rst->bbox.x_max -= x0;
+ rst->bbox.y_min -= y0;
+ rst->bbox.y_max -= y0;
if (!check_capacity(rst, 1, rst->size[0]))
return false;
int32_t size_x = (int32_t) width << 6;
int32_t size_y = (int32_t) height << 6;
- if (rst->x_max >= size_x) {
+ if (rst->bbox.x_max >= size_x) {
polyline_split_horz(rst->linebuf[0], n_lines,
rst->linebuf[0], n_lines,
rst->linebuf[1], n_unused,
winding, size_x);
winding[0] = winding[1] = 0;
}
- if (rst->y_max >= size_y) {
+ if (rst->bbox.y_max >= size_y) {
polyline_split_vert(rst->linebuf[0], n_lines,
rst->linebuf[0], n_lines,
rst->linebuf[1], n_unused,
winding, size_y);
winding[0] = winding[1] = 0;
}
- if (rst->x_min <= 0) {
+ if (rst->bbox.x_min <= 0) {
polyline_split_horz(rst->linebuf[0], n_lines,
rst->linebuf[1], n_unused,
rst->linebuf[0], n_lines,
winding, 0);
}
- if (rst->y_min <= 0) {
+ if (rst->bbox.y_min <= 0) {
polyline_split_vert(rst->linebuf[0], n_lines,
rst->linebuf[1], n_unused,
rst->linebuf[0], n_lines,
int outline_error; // acceptable error (in 1/64 pixel units)
// usable after rasterizer_set_outline
- int32_t x_min, x_max, y_min, y_max;
+ ASS_Rect bbox;
// internal buffers
struct segment *linebuf[2];
}
-static inline void rectangle_reset(ASS_Rect *rect)
-{
- rect->x_min = rect->y_min = INT32_MAX;
- rect->x_max = rect->y_max = INT32_MIN;
-}
-
static inline void rectangle_combine(ASS_Rect *rect, const Bitmap *bm, int x, int y)
{
- rect->x_min = FFMIN(rect->x_min, x + bm->left);
- rect->y_min = FFMIN(rect->y_min, y + bm->top);
- rect->x_max = FFMAX(rect->x_max, x + bm->left + bm->w);
- rect->y_max = FFMAX(rect->y_max, y + bm->top + bm->h);
+ x += bm->left;
+ y += bm->top;
+ rectangle_update(rect, x, y, x + bm->w, y + bm->h);
}
// Convert glyphs to bitmaps, combine them, apply blur, generate shadows.