annotate libass/ass_drawing.c @ 34175:a345e7162d0a

Move TranslateFilename() to util/string.c. Now that the Win32 GUI uses symbolic constants for its messages, the code of TranslateFilename() both GUIs use is almost identical. So, share the code.
author ib
date Wed, 26 Oct 2011 15:14:06 +0000
parents 88eebbbbd6a0
children 6e7f60f6f9d4
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
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 32556
diff changeset
121 if (drawing->library)
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 32556
diff changeset
122 ass_msg(drawing->library, MSGL_V,
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 32556
diff changeset
123 "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
124 ol->n_contours);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
125
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
126 if (raw_mode)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
127 return;
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 drawing->glyph->root.advance.x = d6_to_d16(bbox.xMax - bbox.xMin);
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 drawing->desc = double_to_d6(-drawing->pbo * drawing->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
132 drawing->asc = bbox.yMax - bbox.yMin + drawing->desc;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
133
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
134 // Place it onto the baseline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
135 offset = (bbox.yMax - bbox.yMin) + double_to_d6(-drawing->pbo *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
136 drawing->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
137 for (i = 0; i < ol->n_points; i++)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
138 ol->points[i].y += offset;
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
142 * \brief Check whether a number of items on the list is available
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 static int token_check_values(ASS_DrawingToken *token, int i, int type)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
145 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
146 int j;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
147 for (j = 0; j < i; j++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
148 if (!token || token->type != type) return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
149 token = token->next;
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
152 return 1;
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
156 * \brief Tokenize a drawing string into a list of ASS_DrawingToken
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
157 * This also expands points for closing b-splines
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 static ASS_DrawingToken *drawing_tokenize(char *str)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
160 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
161 char *p = str;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
162 int i, val, type = -1, is_set = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
163 FT_Vector point = {0, 0};
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
164
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
165 ASS_DrawingToken *root = NULL, *tail = NULL, *spline_start = NULL;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
166
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
167 while (*p) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
168 if (*p == 'c' && spline_start) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
169 // Close b-splines: add the first three points of the b-spline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
170 // back to the end
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
171 if (token_check_values(spline_start->next, 2, TOKEN_B_SPLINE)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
172 for (i = 0; i < 3; i++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
173 tail->next = calloc(1, sizeof(ASS_DrawingToken));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
174 tail->next->prev = tail;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
175 tail = tail->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
176 tail->type = TOKEN_B_SPLINE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
177 tail->point = spline_start->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
178 spline_start = spline_start->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
179 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
180 spline_start = NULL;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
181 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
182 } else if (!is_set && mystrtoi(&p, &val)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
183 point.x = val;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
184 is_set = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
185 p--;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
186 } else if (is_set == 1 && mystrtoi(&p, &val)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
187 point.y = val;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
188 is_set = 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
189 p--;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
190 } else if (*p == 'm')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
191 type = TOKEN_MOVE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
192 else if (*p == 'n')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
193 type = TOKEN_MOVE_NC;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
194 else if (*p == 'l')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
195 type = TOKEN_LINE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
196 else if (*p == 'b')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
197 type = TOKEN_CUBIC_BEZIER;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
198 else if (*p == 'q')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
199 type = TOKEN_CONIC_BEZIER;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
200 else if (*p == 's')
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
201 type = TOKEN_B_SPLINE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
202 // We're simply ignoring TOKEN_EXTEND_B_SPLINE here.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
203 // This is not harmful at all, since it can be ommitted with
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
204 // similar result (the spline is extended anyway).
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
205
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
206 if (type != -1 && is_set == 2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
207 if (root) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
208 tail->next = calloc(1, sizeof(ASS_DrawingToken));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
209 tail->next->prev = tail;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
210 tail = tail->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
211 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
212 root = tail = calloc(1, sizeof(ASS_DrawingToken));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
213 tail->type = type;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
214 tail->point = point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
215 is_set = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
216 if (type == TOKEN_B_SPLINE && !spline_start)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
217 spline_start = tail->prev;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
218 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
219 p++;
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
222 return root;
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
226 * \brief Free a list of tokens
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
227 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
228 static void drawing_free_tokens(ASS_DrawingToken *token)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
229 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
230 while (token) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
231 ASS_DrawingToken *at = token;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
232 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
233 free(at);
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
237 /*
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
238 * \brief Update drawing cbox
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
239 */
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
240 static inline void update_cbox(ASS_Drawing *drawing, FT_Vector *point)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
241 {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
242 FT_BBox *box = &drawing->cbox;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
243
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
244 box->xMin = FFMIN(box->xMin, point->x);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
245 box->xMax = FFMAX(box->xMax, point->x);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
246 box->yMin = FFMIN(box->yMin, point->y);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
247 box->yMax = FFMAX(box->yMax, point->y);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
248 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
249
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
250 /*
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
251 * \brief Translate and scale a point coordinate according to baseline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
252 * offset and scale.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
253 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
254 static inline void translate_point(ASS_Drawing *drawing, FT_Vector *point)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
255 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
256 point->x = drawing->point_scale_x * point->x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
257 point->y = drawing->point_scale_y * -point->y;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
258
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
259 update_cbox(drawing, point);
30200
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
263 * \brief Evaluate a curve into lines
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
264 * 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
265 * implementation of the De Casteljau algorithm.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
266 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
267 static void drawing_evaluate_curve(ASS_Drawing *drawing,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
268 ASS_DrawingToken *token, char spline,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
269 int started)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
270 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
271 double cx3, cx2, cx1, cx0, cy3, cy2, cy1, cy0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
272 double t, h, max_accel, max_accel1, max_accel2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
273 FT_Vector cur = {0, 0};
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
274
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
275 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
276 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
277 int x0 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
278 int y0 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
279 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
280 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
281 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
282 int x1 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
283 int y1 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
284 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
285 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
286 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
287 int x2 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
288 int y2 = cur.y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
289 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
290 cur = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
291 translate_point(drawing, &cur);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
292 int x3 = cur.x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
293 int y3 = cur.y;
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 if (spline) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
296 // 1 [-1 +3 -3 +1]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
297 // - * [+3 -6 +3 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
298 // 6 [-3 0 +3 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
299 // [+1 +4 +1 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
300
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
301 double div6 = 1.0/6.0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
302
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
303 cx3 = div6*(- x0+3*x1-3*x2+x3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
304 cx2 = div6*( 3*x0-6*x1+3*x2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
305 cx1 = div6*(-3*x0 +3*x2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
306 cx0 = div6*( x0+4*x1+1*x2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
307
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
308 cy3 = div6*(- y0+3*y1-3*y2+y3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
309 cy2 = div6*( 3*y0-6*y1+3*y2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
310 cy1 = div6*(-3*y0 +3*y2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
311 cy0 = div6*( y0+4*y1+1*y2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
312 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
313 // [-1 +3 -3 +1]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
314 // [+3 -6 +3 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
315 // [-3 +3 0 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
316 // [+1 0 0 0]
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
317
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
318 cx3 = - x0+3*x1-3*x2+x3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
319 cx2 = 3*x0-6*x1+3*x2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
320 cx1 = -3*x0+3*x1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
321 cx0 = x0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
322
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
323 cy3 = - y0+3*y1-3*y2+y3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
324 cy2 = 3*y0-6*y1+3*y2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
325 cy1 = -3*y0+3*y1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
326 cy0 = y0;
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
329 max_accel1 = fabs(2 * cy2) + fabs(6 * cy3);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
330 max_accel2 = fabs(2 * cx2) + fabs(6 * cx3);
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 max_accel = FFMAX(max_accel1, max_accel2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
333 h = 1.0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
334
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
335 if (max_accel > CURVE_ACCURACY)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
336 h = sqrt(CURVE_ACCURACY / max_accel);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
337
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
338 if (!started) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
339 cur.x = cx0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
340 cur.y = cy0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
341 drawing_add_point(drawing, &cur);
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
344 for (t = 0; t < 1.0; t += h) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
345 cur.x = cx0 + t * (cx1 + t * (cx2 + t * cx3));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
346 cur.y = cy0 + t * (cy1 + t * (cy2 + t * cy3));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
347 drawing_add_point(drawing, &cur);
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
350 cur.x = cx0 + cx1 + cx2 + cx3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
351 cur.y = cy0 + cy1 + cy2 + cy3;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
352 drawing_add_point(drawing, &cur);
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
356 * \brief Create and initialize a new drawing and return it
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 ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font,
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
359 FT_Library lib)
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
360 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
361 ASS_Drawing *drawing;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
362
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
363 drawing = calloc(1, sizeof(*drawing));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
364 drawing->text = calloc(1, DRAWING_INITIAL_SIZE);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
365 drawing->size = DRAWING_INITIAL_SIZE;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
366 drawing->cbox.xMin = drawing->cbox.yMin = INT_MAX;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
367 drawing->cbox.xMax = drawing->cbox.yMax = INT_MIN;
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
368 drawing->fontconfig_priv = fontconfig_priv;
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
369 drawing->font = font;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
370 drawing->ftlibrary = lib;
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 32556
diff changeset
371 if (font)
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 32556
diff changeset
372 drawing->library = font->library;
30200
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 drawing->scale_x = 1.;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
375 drawing->scale_y = 1.;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
376 drawing->max_contours = GLYPH_INITIAL_CONTOURS;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
377 drawing->max_points = GLYPH_INITIAL_POINTS;
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 return drawing;
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
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 * \brief Free a 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 void ass_drawing_free(ASS_Drawing* drawing)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
386 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
387 if (drawing) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
388 free(drawing->text);
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 free(drawing);
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
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 * \brief Add one ASCII character to the drawing text buffer
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 void ass_drawing_add_char(ASS_Drawing* drawing, char symbol)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
397 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
398 drawing->text[drawing->i++] = symbol;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
399 drawing->text[drawing->i] = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
400
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
401 if (drawing->i + 1 >= drawing->size) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
402 drawing->size *= 2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
403 drawing->text = realloc(drawing->text, drawing->size);
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
407 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
408 * \brief Create a hashcode for the drawing
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
409 * XXX: To avoid collisions a better hash algorithm might be useful.
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 void ass_drawing_hash(ASS_Drawing* drawing)
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 drawing->hash = fnv_32a_str(drawing->text, FNV1_32A_INIT);
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
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 * \brief Convert token list to outline. Calls the line and curve evaluators.
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 FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
420 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
421 int started = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
422 ASS_DrawingToken *token;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
423 FT_Vector pen = {0, 0};
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
424
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
425 if (drawing->font)
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
426 drawing_make_glyph(drawing, drawing->fontconfig_priv, drawing->font);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
427 if (!drawing->glyph)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
428 return NULL;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
429
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
430 drawing->tokens = drawing_tokenize(drawing->text);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
431 drawing_prepare(drawing);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
432
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
433 token = drawing->tokens;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
434 while (token) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
435 // Draw something according to current command
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
436 switch (token->type) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
437 case TOKEN_MOVE_NC:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
438 pen = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
439 translate_point(drawing, &pen);
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 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
442 case TOKEN_MOVE:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
443 pen = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
444 translate_point(drawing, &pen);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
445 if (started) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
446 drawing_close_shape(drawing);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
447 started = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
448 }
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 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
451 case TOKEN_LINE: {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
452 FT_Vector to;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
453 to = token->point;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
454 translate_point(drawing, &to);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
455 if (!started) drawing_add_point(drawing, &pen);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
456 drawing_add_point(drawing, &to);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
457 started = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
458 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
459 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
460 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
461 case TOKEN_CUBIC_BEZIER:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
462 if (token_check_values(token, 3, TOKEN_CUBIC_BEZIER) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
463 token->prev) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
464 drawing_evaluate_curve(drawing, token->prev, 0, started);
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 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
467 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
468 started = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
469 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
470 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
471 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
472 case TOKEN_B_SPLINE:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
473 if (token_check_values(token, 3, TOKEN_B_SPLINE) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
474 token->prev) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
475 drawing_evaluate_curve(drawing, token->prev, 1, started);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
476 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
477 started = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
478 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
479 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
480 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
481 default:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
482 token = token->next;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
483 break;
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 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
486
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
487 drawing_finish(drawing, raw_mode);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
488 drawing_free_tokens(drawing->tokens);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
489 return &drawing->glyph;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
490 }