/* * \brief Tokenize a drawing string into a list of ASS_DrawingToken * This also expands points for closing b-splines */ static ASS_DrawingToken *drawing_tokenize(char *str) { char *p = str; int i, val, type = -1, is_set = 0; FT_Vector point = {0, 0}; ASS_DrawingToken *root = NULL, *tail = NULL, *spline_start = NULL; while (*p) { if (*p == 'c' && spline_start) { // Close b-splines: add the first three points of the b-spline // back to the end if (token_check_values(spline_start->next, 2, TOKEN_B_SPLINE)) { for (i = 0; i < 3; i++) { tail->next = calloc(1, sizeof(ASS_DrawingToken)); tail->next->prev = tail; tail = tail->next; tail->type = TOKEN_B_SPLINE; tail->point = spline_start->point; spline_start = spline_start->next; } spline_start = NULL; } } else if (!is_set && mystrtoi(&p, &val)) { point.x = val; is_set = 1; p--; } else if (is_set == 1 && mystrtoi(&p, &val)) { point.y = val; is_set = 2; p--; } else if (*p == 'm') type = TOKEN_MOVE; else if (*p == 'n') type = TOKEN_MOVE_NC; else if (*p == 'l') type = TOKEN_LINE; else if (*p == 'b') type = TOKEN_CUBIC_BEZIER; else if (*p == 'q') type = TOKEN_CONIC_BEZIER; else if (*p == 's') type = TOKEN_B_SPLINE; // We're simply ignoring TOKEN_EXTEND_B_SPLINE here. // This is not harmful at all, since it can be ommitted with // similar result (the spline is extended anyway). if (type != -1 && is_set == 2) { if (root) { tail->next = calloc(1, sizeof(ASS_DrawingToken)); tail->next->prev = tail; tail = tail->next; } else root = tail = calloc(1, sizeof(ASS_DrawingToken)); tail->type = type; tail->point = point; is_set = 0; if (type == TOKEN_B_SPLINE && !spline_start) spline_start = tail->prev; } p++; } return root; }
static inline int argtoi(struct arg arg) { int value; mystrtoi(&arg.start, &value); return value; }