annotate libass/ass_drawing.c @ 32676:db882cd69776

Do not #define _WIN32 on the command line for Cygwin. Newer Cygwin versions no longer do this and hopefully we should be able to survive without this hack as well. This change necessitates adapting two #ifdefs in the MPlayer codebase. It is committed untested as I do not have access to a Cygwin system.
author diego
date Thu, 06 Jan 2011 12:42:59 +0000
parents 34215c3e6e10
children 88eebbbbd6a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
1 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
2 * Copyright (C) 2009 Grigori Goronzy <greg@geekmind.org>
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
3 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
4 * This file is part of libass.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
5 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
6 * Permission to use, copy, modify, and distribute this software for any
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
9 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
17 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
18
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
19 #include <ft2build.h>
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
20 #include FT_GLYPH_H
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
21 #include FT_OUTLINE_H
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
22 #include FT_BBOX_H
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
23 #include <math.h>
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
24
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
25 #include "ass_utils.h"
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
26 #include "ass_font.h"
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
27 #include "ass_drawing.h"
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
28
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
29 #define CURVE_ACCURACY 64.0
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
30 #define GLYPH_INITIAL_POINTS 100
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
31 #define GLYPH_INITIAL_CONTOURS 5
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
32
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
33 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
34 * \brief Get and prepare a FreeType glyph
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
35 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
36 static void drawing_make_glyph(ASS_Drawing *drawing, void *fontconfig_priv,
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
37 ASS_Font *font)
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
38 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
39 FT_OutlineGlyph glyph;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
40
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
41 // This is hacky...
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
42 glyph = (FT_OutlineGlyph) ass_font_get_glyph(fontconfig_priv, font,
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
43 (uint32_t) ' ', 0, 0);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
44 if (glyph) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
45 FT_Outline_Done(drawing->ftlibrary, &glyph->outline);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
46 FT_Outline_New(drawing->ftlibrary, GLYPH_INITIAL_POINTS,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
47 GLYPH_INITIAL_CONTOURS, &glyph->outline);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
48
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
49 glyph->outline.n_contours = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
50 glyph->outline.n_points = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
51 glyph->root.advance.x = glyph->root.advance.y = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
52 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
53 drawing->glyph = glyph;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
54 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
55
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
56 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
57 * \brief Add a single point to a contour.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
58 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
59 static inline void drawing_add_point(ASS_Drawing *drawing,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
60 FT_Vector *point)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
61 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
62 FT_Outline *ol = &drawing->glyph->outline;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
63
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
64 if (ol->n_points >= drawing->max_points) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
65 drawing->max_points *= 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
66 ol->points = realloc(ol->points, sizeof(FT_Vector) *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
67 drawing->max_points);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
68 ol->tags = realloc(ol->tags, drawing->max_points);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
69 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
70
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
71 ol->points[ol->n_points].x = point->x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
72 ol->points[ol->n_points].y = point->y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
73 ol->tags[ol->n_points] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
74 ol->n_points++;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
75 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
76
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
77 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
78 * \brief Close a contour and check glyph size overflow.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
79 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
80 static inline void drawing_close_shape(ASS_Drawing *drawing)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
81 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
82 FT_Outline *ol = &drawing->glyph->outline;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
83
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
84 if (ol->n_contours >= drawing->max_contours) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
85 drawing->max_contours *= 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
86 ol->contours = realloc(ol->contours, sizeof(short) *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
87 drawing->max_contours);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
88 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
89
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
90 if (ol->n_points) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
91 ol->contours[ol->n_contours] = ol->n_points - 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
92 ol->n_contours++;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
93 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
94 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
95
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
96 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
97 * \brief Prepare drawing for parsing. This just sets a few parameters.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
98 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
99 static void drawing_prepare(ASS_Drawing *drawing)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
100 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
101 // Scaling parameters
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
102 drawing->point_scale_x = drawing->scale_x *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
103 64.0 / (1 << (drawing->scale - 1));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
104 drawing->point_scale_y = drawing->scale_y *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
105 64.0 / (1 << (drawing->scale - 1));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
106 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
107
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
108 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
109 * \brief Finish a drawing. This only sets the horizontal advance according
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
110 * to the glyph's bbox at the moment.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
111 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
112 static void drawing_finish(ASS_Drawing *drawing, int raw_mode)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
113 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
114 int i, offset;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
115 FT_BBox bbox = drawing->cbox;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
116 FT_Outline *ol = &drawing->glyph->outline;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
117
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
118 // Close the last contour
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
119 drawing_close_shape(drawing);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
120
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
121 ass_msg(drawing->library, MSGL_V,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
122 "Parsed drawing with %d points and %d contours", ol->n_points,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
123 ol->n_contours);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
124
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
125 if (raw_mode)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
126 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
127
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
128 drawing->glyph->root.advance.x = d6_to_d16(bbox.xMax - bbox.xMin);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
129
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
130 drawing->desc = double_to_d6(-drawing->pbo * drawing->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
131 drawing->asc = bbox.yMax - bbox.yMin + drawing->desc;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
132
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
133 // Place it onto the baseline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
134 offset = (bbox.yMax - bbox.yMin) + double_to_d6(-drawing->pbo *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
135 drawing->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
136 for (i = 0; i < ol->n_points; i++)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
137 ol->points[i].y += offset;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
138 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
139
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
140 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
141 * \brief Check whether a number of items on the list is available
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
142 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
143 static int token_check_values(ASS_DrawingToken *token, int i, int type)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
144 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
145 int j;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
146 for (j = 0; j < i; j++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
147 if (!token || token->type != type) return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
148 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
149 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
150
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
151 return 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
152 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
153
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
154 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
155 * \brief Tokenize a drawing string into a list of ASS_DrawingToken
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
156 * This also expands points for closing b-splines
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
157 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
158 static ASS_DrawingToken *drawing_tokenize(char *str)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
159 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
160 char *p = str;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
161 int i, val, type = -1, is_set = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
162 FT_Vector point = {0, 0};
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
163
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
164 ASS_DrawingToken *root = NULL, *tail = NULL, *spline_start = NULL;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
165
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
166 while (*p) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
167 if (*p == 'c' && spline_start) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
168 // Close b-splines: add the first three points of the b-spline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
169 // back to the end
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
170 if (token_check_values(spline_start->next, 2, TOKEN_B_SPLINE)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
171 for (i = 0; i < 3; i++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
172 tail->next = calloc(1, sizeof(ASS_DrawingToken));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
173 tail->next->prev = tail;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
174 tail = tail->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
175 tail->type = TOKEN_B_SPLINE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
176 tail->point = spline_start->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
177 spline_start = spline_start->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
178 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
179 spline_start = NULL;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
180 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
181 } else if (!is_set && mystrtoi(&p, &val)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
182 point.x = val;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
183 is_set = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
184 p--;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
185 } else if (is_set == 1 && mystrtoi(&p, &val)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
186 point.y = val;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
187 is_set = 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
188 p--;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
189 } else if (*p == 'm')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
190 type = TOKEN_MOVE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
191 else if (*p == 'n')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
192 type = TOKEN_MOVE_NC;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
193 else if (*p == 'l')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
194 type = TOKEN_LINE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
195 else if (*p == 'b')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
196 type = TOKEN_CUBIC_BEZIER;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
197 else if (*p == 'q')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
198 type = TOKEN_CONIC_BEZIER;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
199 else if (*p == 's')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
200 type = TOKEN_B_SPLINE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
201 // We're simply ignoring TOKEN_EXTEND_B_SPLINE here.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
202 // This is not harmful at all, since it can be ommitted with
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
203 // similar result (the spline is extended anyway).
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
204
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
205 if (type != -1 && is_set == 2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
206 if (root) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
207 tail->next = calloc(1, sizeof(ASS_DrawingToken));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
208 tail->next->prev = tail;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
209 tail = tail->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
210 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
211 root = tail = calloc(1, sizeof(ASS_DrawingToken));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
212 tail->type = type;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
213 tail->point = point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
214 is_set = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
215 if (type == TOKEN_B_SPLINE && !spline_start)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
216 spline_start = tail->prev;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
217 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
218 p++;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
219 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
220
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
221 return root;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
222 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
223
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
224 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
225 * \brief Free a list of tokens
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
226 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
227 static void drawing_free_tokens(ASS_DrawingToken *token)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
228 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
229 while (token) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
230 ASS_DrawingToken *at = token;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
231 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
232 free(at);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
233 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
234 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
235
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
236 /*
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
237 * \brief Update drawing cbox
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
238 */
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
239 static inline void update_cbox(ASS_Drawing *drawing, FT_Vector *point)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
240 {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
241 FT_BBox *box = &drawing->cbox;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
242
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
243 box->xMin = FFMIN(box->xMin, point->x);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
244 box->xMax = FFMAX(box->xMax, point->x);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
245 box->yMin = FFMIN(box->yMin, point->y);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
246 box->yMax = FFMAX(box->yMax, point->y);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
247 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
248
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
249 /*
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
250 * \brief Translate and scale a point coordinate according to baseline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
251 * offset and scale.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
252 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
253 static inline void translate_point(ASS_Drawing *drawing, FT_Vector *point)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
254 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
255 point->x = drawing->point_scale_x * point->x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
256 point->y = drawing->point_scale_y * -point->y;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
257
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
258 update_cbox(drawing, point);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
259 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
260
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
261 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
262 * \brief Evaluate a curve into lines
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
263 * This curve evaluator is also used in VSFilter (RTS.cpp); it's a simple
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
264 * implementation of the De Casteljau algorithm.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
265 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
266 static void drawing_evaluate_curve(ASS_Drawing *drawing,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
267 ASS_DrawingToken *token, char spline,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
268 int started)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
269 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
270 double cx3, cx2, cx1, cx0, cy3, cy2, cy1, cy0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
271 double t, h, max_accel, max_accel1, max_accel2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
272 FT_Vector cur = {0, 0};
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
273
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
274 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
275 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
276 int x0 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
277 int y0 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
278 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
279 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
280 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
281 int x1 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
282 int y1 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
283 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
284 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
285 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
286 int x2 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
287 int y2 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
288 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
289 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
290 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
291 int x3 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
292 int y3 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
293
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
294 if (spline) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
295 // 1 [-1 +3 -3 +1]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
296 // - * [+3 -6 +3 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
297 // 6 [-3 0 +3 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
298 // [+1 +4 +1 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
299
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
300 double div6 = 1.0/6.0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
301
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
302 cx3 = div6*(- x0+3*x1-3*x2+x3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
303 cx2 = div6*( 3*x0-6*x1+3*x2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
304 cx1 = div6*(-3*x0 +3*x2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
305 cx0 = div6*( x0+4*x1+1*x2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
306
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
307 cy3 = div6*(- y0+3*y1-3*y2+y3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
308 cy2 = div6*( 3*y0-6*y1+3*y2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
309 cy1 = div6*(-3*y0 +3*y2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
310 cy0 = div6*( y0+4*y1+1*y2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
311 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
312 // [-1 +3 -3 +1]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
313 // [+3 -6 +3 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
314 // [-3 +3 0 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
315 // [+1 0 0 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
316
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
317 cx3 = - x0+3*x1-3*x2+x3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
318 cx2 = 3*x0-6*x1+3*x2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
319 cx1 = -3*x0+3*x1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
320 cx0 = x0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
321
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
322 cy3 = - y0+3*y1-3*y2+y3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
323 cy2 = 3*y0-6*y1+3*y2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
324 cy1 = -3*y0+3*y1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
325 cy0 = y0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
326 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
327
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
328 max_accel1 = fabs(2 * cy2) + fabs(6 * cy3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
329 max_accel2 = fabs(2 * cx2) + fabs(6 * cx3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
330
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
331 max_accel = FFMAX(max_accel1, max_accel2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
332 h = 1.0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
333
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
334 if (max_accel > CURVE_ACCURACY)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
335 h = sqrt(CURVE_ACCURACY / max_accel);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
336
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
337 if (!started) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
338 cur.x = cx0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
339 cur.y = cy0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
340 drawing_add_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
341 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
342
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
343 for (t = 0; t < 1.0; t += h) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
344 cur.x = cx0 + t * (cx1 + t * (cx2 + t * cx3));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
345 cur.y = cy0 + t * (cy1 + t * (cy2 + t * cy3));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
346 drawing_add_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
347 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
348
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
349 cur.x = cx0 + cx1 + cx2 + cx3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
350 cur.y = cy0 + cy1 + cy2 + cy3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
351 drawing_add_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
352 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
353
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
354 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
355 * \brief Create and initialize a new drawing and return it
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
356 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
357 ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font,
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
358 FT_Library lib)
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
359 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
360 ASS_Drawing *drawing;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
361
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
362 drawing = calloc(1, sizeof(*drawing));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
363 drawing->text = calloc(1, DRAWING_INITIAL_SIZE);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
364 drawing->size = DRAWING_INITIAL_SIZE;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
365 drawing->cbox.xMin = drawing->cbox.yMin = INT_MAX;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
366 drawing->cbox.xMax = drawing->cbox.yMax = INT_MIN;
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
367 drawing->fontconfig_priv = fontconfig_priv;
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
368 drawing->font = font;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
369 drawing->ftlibrary = lib;
32556
34215c3e6e10 Check the validity of an argument, font.
komh
parents: 31875
diff changeset
370 drawing->library = font ? font->library : NULL;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
371
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
372 drawing->scale_x = 1.;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
373 drawing->scale_y = 1.;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
374 drawing->max_contours = GLYPH_INITIAL_CONTOURS;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
375 drawing->max_points = GLYPH_INITIAL_POINTS;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
376
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
377 return drawing;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
378 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
379
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
380 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
381 * \brief Free a drawing
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
382 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
383 void ass_drawing_free(ASS_Drawing* drawing)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
384 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
385 if (drawing) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
386 free(drawing->text);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
387 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
388 free(drawing);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
389 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
390
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
391 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
392 * \brief Add one ASCII character to the drawing text buffer
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
393 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
394 void ass_drawing_add_char(ASS_Drawing* drawing, char symbol)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
395 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
396 drawing->text[drawing->i++] = symbol;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
397 drawing->text[drawing->i] = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
398
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
399 if (drawing->i + 1 >= drawing->size) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
400 drawing->size *= 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
401 drawing->text = realloc(drawing->text, drawing->size);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
402 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
403 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
404
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
405 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
406 * \brief Create a hashcode for the drawing
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
407 * XXX: To avoid collisions a better hash algorithm might be useful.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
408 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
409 void ass_drawing_hash(ASS_Drawing* drawing)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
410 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
411 drawing->hash = fnv_32a_str(drawing->text, FNV1_32A_INIT);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
412 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
413
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
414 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
415 * \brief Convert token list to outline. Calls the line and curve evaluators.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
416 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
417 FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
418 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
419 int started = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
420 ASS_DrawingToken *token;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
421 FT_Vector pen = {0, 0};
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
422
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
423 if (drawing->font)
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
424 drawing_make_glyph(drawing, drawing->fontconfig_priv, drawing->font);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
425 if (!drawing->glyph)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
426 return NULL;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
427
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
428 drawing->tokens = drawing_tokenize(drawing->text);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
429 drawing_prepare(drawing);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
430
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
431 token = drawing->tokens;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
432 while (token) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
433 // Draw something according to current command
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
434 switch (token->type) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
435 case TOKEN_MOVE_NC:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
436 pen = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
437 translate_point(drawing, &pen);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
438 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
439 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
440 case TOKEN_MOVE:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
441 pen = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
442 translate_point(drawing, &pen);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
443 if (started) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
444 drawing_close_shape(drawing);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
445 started = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
446 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
447 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
448 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
449 case TOKEN_LINE: {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
450 FT_Vector to;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
451 to = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
452 translate_point(drawing, &to);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
453 if (!started) drawing_add_point(drawing, &pen);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
454 drawing_add_point(drawing, &to);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
455 started = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
456 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
457 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
458 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
459 case TOKEN_CUBIC_BEZIER:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
460 if (token_check_values(token, 3, TOKEN_CUBIC_BEZIER) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
461 token->prev) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
462 drawing_evaluate_curve(drawing, token->prev, 0, started);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
463 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
464 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
465 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
466 started = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
467 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
468 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
469 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
470 case TOKEN_B_SPLINE:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
471 if (token_check_values(token, 3, TOKEN_B_SPLINE) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
472 token->prev) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
473 drawing_evaluate_curve(drawing, token->prev, 1, started);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
474 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
475 started = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
476 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
477 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
478 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
479 default:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
480 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
481 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
482 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
483 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
484
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
485 drawing_finish(drawing, raw_mode);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
486 drawing_free_tokens(drawing->tokens);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
487 return &drawing->glyph;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
488 }