annotate libass/ass_drawing.c @ 35965:7038dec225b1

Fix KEY_BACKSPACE, KEY_DELETE and KEY_ESC to map to their ASCII equivalents. Also avoids some issues with our X11 key string lookup ending up translating these to their ASCII values, which before resulted in "unknown key" messages.
author reimar
date Mon, 25 Mar 2013 22:54:54 +0000
parents 49fc594fda43
children
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_OUTLINE_H
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
21 #include FT_BBOX_H
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
22 #include <math.h>
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
23
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
24 #include "ass_utils.h"
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
25 #include "ass_drawing.h"
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
26
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
27 #define CURVE_ACCURACY 64.0
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
28 #define GLYPH_INITIAL_POINTS 100
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
29 #define GLYPH_INITIAL_CONTOURS 5
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
30
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
31 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
32 * \brief Add a single point to a contour.
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 static inline void drawing_add_point(ASS_Drawing *drawing,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
35 FT_Vector *point)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
36 {
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
37 FT_Outline *ol = &drawing->outline;
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 if (ol->n_points >= drawing->max_points) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
40 drawing->max_points *= 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
41 ol->points = realloc(ol->points, sizeof(FT_Vector) *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
42 drawing->max_points);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
43 ol->tags = realloc(ol->tags, drawing->max_points);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
44 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
45
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
46 ol->points[ol->n_points].x = point->x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
47 ol->points[ol->n_points].y = point->y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
48 ol->tags[ol->n_points] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
49 ol->n_points++;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
50 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
51
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
52 /*
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
53 * \brief Close a contour and check outline size overflow.
30200
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 static inline void drawing_close_shape(ASS_Drawing *drawing)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
56 {
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
57 FT_Outline *ol = &drawing->outline;
30200
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 if (ol->n_contours >= drawing->max_contours) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
60 drawing->max_contours *= 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
61 ol->contours = realloc(ol->contours, sizeof(short) *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
62 drawing->max_contours);
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
65 if (ol->n_points) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
66 ol->contours[ol->n_contours] = ol->n_points - 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
67 ol->n_contours++;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
68 }
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
72 * \brief Prepare drawing for parsing. This just sets a few parameters.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
73 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
74 static void drawing_prepare(ASS_Drawing *drawing)
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 // Scaling parameters
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
77 drawing->point_scale_x = drawing->scale_x *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
78 64.0 / (1 << (drawing->scale - 1));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
79 drawing->point_scale_y = drawing->scale_y *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
80 64.0 / (1 << (drawing->scale - 1));
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
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 * \brief Finish a drawing. This only sets the horizontal advance according
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
85 * to the outline's bbox at the moment.
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
86 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
87 static void drawing_finish(ASS_Drawing *drawing, int raw_mode)
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 int i, offset;
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34295
diff changeset
90 double pbo;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
91 FT_BBox bbox = drawing->cbox;
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
92 FT_Outline *ol = &drawing->outline;
30200
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 // Close the last contour
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
95 drawing_close_shape(drawing);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
96
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 32556
diff changeset
97 if (drawing->library)
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 32556
diff changeset
98 ass_msg(drawing->library, MSGL_V,
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 32556
diff changeset
99 "Parsed drawing with %d points and %d contours", ol->n_points,
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 32556
diff changeset
100 ol->n_contours);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
101
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
102 if (raw_mode)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
103 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
104
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
105 drawing->advance.x = bbox.xMax - bbox.xMin;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
106
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34295
diff changeset
107 pbo = drawing->pbo / (64.0 / (1 << (drawing->scale - 1)));
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34295
diff changeset
108 drawing->desc = double_to_d6(-pbo * drawing->scale_y);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
109 drawing->asc = bbox.yMax - bbox.yMin + drawing->desc;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
110
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
111 // Place it onto the baseline
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34295
diff changeset
112 offset = (bbox.yMax - bbox.yMin) + double_to_d6(-pbo *
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
113 drawing->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
114 for (i = 0; i < ol->n_points; i++)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
115 ol->points[i].y += offset;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
116 }
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
119 * \brief Check whether a number of items on the list is available
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 static int token_check_values(ASS_DrawingToken *token, int i, int type)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
122 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
123 int j;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
124 for (j = 0; j < i; j++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
125 if (!token || token->type != type) return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
126 token = token->next;
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
129 return 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
130 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
131
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 * \brief Tokenize a drawing string into a list of ASS_DrawingToken
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
134 * This also expands points for closing b-splines
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
135 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
136 static ASS_DrawingToken *drawing_tokenize(char *str)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
137 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
138 char *p = str;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
139 int i, val, type = -1, is_set = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
140 FT_Vector point = {0, 0};
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
141
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
142 ASS_DrawingToken *root = NULL, *tail = NULL, *spline_start = NULL;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
143
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
144 while (*p) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
145 if (*p == 'c' && spline_start) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
146 // Close b-splines: add the first three points of the b-spline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
147 // back to the end
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
148 if (token_check_values(spline_start->next, 2, TOKEN_B_SPLINE)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
149 for (i = 0; i < 3; i++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
150 tail->next = calloc(1, sizeof(ASS_DrawingToken));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
151 tail->next->prev = tail;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
152 tail = tail->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
153 tail->type = TOKEN_B_SPLINE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
154 tail->point = spline_start->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
155 spline_start = spline_start->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
156 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
157 spline_start = NULL;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
158 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
159 } else if (!is_set && mystrtoi(&p, &val)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
160 point.x = val;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
161 is_set = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
162 p--;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
163 } else if (is_set == 1 && mystrtoi(&p, &val)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
164 point.y = val;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
165 is_set = 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
166 p--;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
167 } else if (*p == 'm')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
168 type = TOKEN_MOVE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
169 else if (*p == 'n')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
170 type = TOKEN_MOVE_NC;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
171 else if (*p == 'l')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
172 type = TOKEN_LINE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
173 else if (*p == 'b')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
174 type = TOKEN_CUBIC_BEZIER;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
175 else if (*p == 'q')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
176 type = TOKEN_CONIC_BEZIER;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
177 else if (*p == 's')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
178 type = TOKEN_B_SPLINE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
179 // We're simply ignoring TOKEN_EXTEND_B_SPLINE here.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
180 // This is not harmful at all, since it can be ommitted with
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
181 // similar result (the spline is extended anyway).
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
182
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
183 if (type != -1 && is_set == 2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
184 if (root) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
185 tail->next = calloc(1, sizeof(ASS_DrawingToken));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
186 tail->next->prev = tail;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
187 tail = tail->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
188 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
189 root = tail = calloc(1, sizeof(ASS_DrawingToken));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
190 tail->type = type;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
191 tail->point = point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
192 is_set = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
193 if (type == TOKEN_B_SPLINE && !spline_start)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
194 spline_start = tail->prev;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
195 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
196 p++;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
197 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
198
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
199 return root;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
200 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
201
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
202 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
203 * \brief Free a list of tokens
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 static void drawing_free_tokens(ASS_DrawingToken *token)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
206 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
207 while (token) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
208 ASS_DrawingToken *at = token;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
209 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
210 free(at);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
211 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
212 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
213
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
214 /*
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
215 * \brief Update drawing cbox
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
216 */
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
217 static inline void update_cbox(ASS_Drawing *drawing, FT_Vector *point)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
218 {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
219 FT_BBox *box = &drawing->cbox;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
220
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
221 box->xMin = FFMIN(box->xMin, point->x);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
222 box->xMax = FFMAX(box->xMax, point->x);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
223 box->yMin = FFMIN(box->yMin, point->y);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
224 box->yMax = FFMAX(box->yMax, point->y);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
225 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
226
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
227 /*
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
228 * \brief Translate and scale a point coordinate according to baseline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
229 * offset and scale.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
230 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
231 static inline void translate_point(ASS_Drawing *drawing, FT_Vector *point)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
232 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
233 point->x = drawing->point_scale_x * point->x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
234 point->y = drawing->point_scale_y * -point->y;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
235
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
236 update_cbox(drawing, point);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
237 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
238
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
239 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
240 * \brief Evaluate a curve into lines
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
241 * 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
242 * implementation of the De Casteljau algorithm.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
243 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
244 static void drawing_evaluate_curve(ASS_Drawing *drawing,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
245 ASS_DrawingToken *token, char spline,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
246 int started)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
247 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
248 double cx3, cx2, cx1, cx0, cy3, cy2, cy1, cy0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
249 double t, h, max_accel, max_accel1, max_accel2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
250 FT_Vector cur = {0, 0};
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
251
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
252 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
253 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
254 int x0 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
255 int y0 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
256 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
257 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
258 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
259 int x1 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
260 int y1 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
261 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
262 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
263 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
264 int x2 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
265 int y2 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
266 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
267 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
268 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
269 int x3 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
270 int y3 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
271
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
272 if (spline) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
273 // 1 [-1 +3 -3 +1]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
274 // - * [+3 -6 +3 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
275 // 6 [-3 0 +3 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
276 // [+1 +4 +1 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
277
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
278 double div6 = 1.0/6.0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
279
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
280 cx3 = div6*(- x0+3*x1-3*x2+x3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
281 cx2 = div6*( 3*x0-6*x1+3*x2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
282 cx1 = div6*(-3*x0 +3*x2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
283 cx0 = div6*( x0+4*x1+1*x2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
284
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
285 cy3 = div6*(- y0+3*y1-3*y2+y3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
286 cy2 = div6*( 3*y0-6*y1+3*y2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
287 cy1 = div6*(-3*y0 +3*y2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
288 cy0 = div6*( y0+4*y1+1*y2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
289 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
290 // [-1 +3 -3 +1]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
291 // [+3 -6 +3 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
292 // [-3 +3 0 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
293 // [+1 0 0 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
294
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
295 cx3 = - x0+3*x1-3*x2+x3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
296 cx2 = 3*x0-6*x1+3*x2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
297 cx1 = -3*x0+3*x1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
298 cx0 = x0;
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 cy3 = - y0+3*y1-3*y2+y3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
301 cy2 = 3*y0-6*y1+3*y2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
302 cy1 = -3*y0+3*y1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
303 cy0 = y0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
304 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
305
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
306 max_accel1 = fabs(2 * cy2) + fabs(6 * cy3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
307 max_accel2 = fabs(2 * cx2) + fabs(6 * cx3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
308
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
309 max_accel = FFMAX(max_accel1, max_accel2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
310 h = 1.0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
311
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
312 if (max_accel > CURVE_ACCURACY)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
313 h = sqrt(CURVE_ACCURACY / max_accel);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
314
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
315 if (!started) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
316 cur.x = cx0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
317 cur.y = cy0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
318 drawing_add_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
319 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
320
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
321 for (t = 0; t < 1.0; t += h) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
322 cur.x = cx0 + t * (cx1 + t * (cx2 + t * cx3));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
323 cur.y = cy0 + t * (cy1 + t * (cy2 + t * cy3));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
324 drawing_add_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
325 }
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 cur.x = cx0 + cx1 + cx2 + cx3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
328 cur.y = cy0 + cy1 + cy2 + cy3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
329 drawing_add_point(drawing, &cur);
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
332 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
333 * \brief Create and initialize a new drawing and return it
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
334 */
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
335 ASS_Drawing *ass_drawing_new(ASS_Library *lib, FT_Library ftlib)
30200
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 ASS_Drawing *drawing;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
338
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
339 drawing = calloc(1, sizeof(*drawing));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
340 drawing->text = calloc(1, DRAWING_INITIAL_SIZE);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
341 drawing->size = DRAWING_INITIAL_SIZE;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
342 drawing->cbox.xMin = drawing->cbox.yMin = INT_MAX;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
343 drawing->cbox.xMax = drawing->cbox.yMax = INT_MIN;
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
344 drawing->ftlibrary = ftlib;
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
345 drawing->library = lib;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
346 drawing->scale_x = 1.;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
347 drawing->scale_y = 1.;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
348 drawing->max_contours = GLYPH_INITIAL_CONTOURS;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
349 drawing->max_points = GLYPH_INITIAL_POINTS;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
350
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
351 FT_Outline_New(drawing->ftlibrary, GLYPH_INITIAL_POINTS,
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
352 GLYPH_INITIAL_CONTOURS, &drawing->outline);
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
353 drawing->outline.n_contours = 0;
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
354 drawing->outline.n_points = 0;
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
355
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
356 return drawing;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
357 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
358
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 * \brief Free a 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 void ass_drawing_free(ASS_Drawing* drawing)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
363 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
364 if (drawing) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
365 free(drawing->text);
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
366 FT_Outline_Done(drawing->ftlibrary, &drawing->outline);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
367 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
368 free(drawing);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
369 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
370
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 * \brief Add one ASCII character to the drawing text buffer
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
373 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
374 void ass_drawing_add_char(ASS_Drawing* drawing, char symbol)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
375 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
376 drawing->text[drawing->i++] = symbol;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
377 drawing->text[drawing->i] = 0;
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 if (drawing->i + 1 >= drawing->size) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
380 drawing->size *= 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
381 drawing->text = realloc(drawing->text, drawing->size);
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 }
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
386 * \brief Create a hashcode for the drawing
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
387 * XXX: To avoid collisions a better hash algorithm might be useful.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
388 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
389 void ass_drawing_hash(ASS_Drawing* drawing)
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 drawing->hash = fnv_32a_str(drawing->text, FNV1_32A_INIT);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
392 }
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
395 * \brief Convert token list to outline. Calls the line and curve evaluators.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
396 */
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
397 FT_Outline *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode)
30200
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 int started = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
400 ASS_DrawingToken *token;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
401 FT_Vector pen = {0, 0};
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 drawing->tokens = drawing_tokenize(drawing->text);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
404 drawing_prepare(drawing);
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 token = drawing->tokens;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
407 while (token) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
408 // Draw something according to current command
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
409 switch (token->type) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
410 case TOKEN_MOVE_NC:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
411 pen = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
412 translate_point(drawing, &pen);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
413 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
414 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
415 case TOKEN_MOVE:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
416 pen = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
417 translate_point(drawing, &pen);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
418 if (started) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
419 drawing_close_shape(drawing);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
420 started = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
421 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
422 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
423 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
424 case TOKEN_LINE: {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
425 FT_Vector to;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
426 to = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
427 translate_point(drawing, &to);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
428 if (!started) drawing_add_point(drawing, &pen);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
429 drawing_add_point(drawing, &to);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
430 started = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
431 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
432 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
433 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
434 case TOKEN_CUBIC_BEZIER:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
435 if (token_check_values(token, 3, TOKEN_CUBIC_BEZIER) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
436 token->prev) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
437 drawing_evaluate_curve(drawing, token->prev, 0, started);
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 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
440 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
441 started = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
442 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
443 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
444 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
445 case TOKEN_B_SPLINE:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
446 if (token_check_values(token, 3, TOKEN_B_SPLINE) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
447 token->prev) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
448 drawing_evaluate_curve(drawing, token->prev, 1, started);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
449 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
450 started = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
451 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
452 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
453 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
454 default:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
455 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
456 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
457 }
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
460 drawing_finish(drawing, raw_mode);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
461 drawing_free_tokens(drawing->tokens);
34295
6e7f60f6f9d4 Update libass to 0.10 release.
reimar
parents: 34011
diff changeset
462 return &drawing->outline;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
463 }