1 /* Copyright (C) 2008 Vincent Penquerc'h.
2 This file is part of the Kate codec library.
3 Written by Vincent Penquerc'h.
4
5 Use, distribution and reproduction of this library is governed
6 by a BSD style source license included with this source in the
7 file 'COPYING'. Please read these terms before distributing. */
8
9
10 %{
11
12 #define KATE_INTERNAL
13 #include "kate_internal.h"
14
15 #include <limits.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdarg.h>
19 #ifdef HAVE_STRING_H
20 #include <string.h>
21 #endif
22 #include <ctype.h>
23 #include "kate/oggkate.h"
24 #ifdef HAVE_PNG
25 #include "kpng.h"
26 #endif
27 #include "katedesc.h"
28 #include "kate_parser.h"
29
30 #define CHECK_KATE_API_ERROR(statement) \
31 do { \
32 int ret=(statement); \
33 if (ret<0) { \
34 yyerror("error in #statement"); \
35 exit(-1); \
36 } \
37 } while(0)
38
39 int nerrors=0;
40 int nwarnings=0;
41
42 static char *temp_macro_name=NULL;
43 static kate_float timebase = (kate_float)0;
44
45 typedef kate_style kd_style;
46 typedef kate_region kd_region;
47
48 typedef struct kd_curve {
49 size_t idx;
50 kate_curve *curve;
51 } kd_curve;
52
53 typedef struct kd_motion {
54 size_t idx;
55 kate_motion *motion;
56 } kd_motion;
57
58 typedef struct kd_palette {
59 kate_palette *palette;
60 } kd_palette;
61
62 typedef struct kd_bitmap {
63 kate_bitmap *bitmap;
64 } kd_bitmap;
65
66 static kate_style kstyle;
67 static kate_region kregion;
68 static kd_palette kpalette;
69 static kd_bitmap kbitmap;
70 static kd_curve kcurve;
71 static kate_font_range *krange=NULL;
72 static kate_font_mapping *kmapping=NULL;
73
74 static size_t nkmotions=0;
75 static kd_motion *kmotions=NULL;
76 static kate_motion *kmotion=NULL;
77
78 static char **style_names=NULL;
79 static char **region_names=NULL;
80 static char **palette_names=NULL;
81 static char **bitmap_names=NULL;
82 static char **curve_names=NULL;
83 static char **motion_names=NULL;
84 static char **font_range_names=NULL;
85 static char **font_mapping_names=NULL;
86
87 static size_t n_local_bitmaps=0;
88 static char **local_bitmap_names=NULL;
89 static kate_bitmap **local_bitmaps=NULL;
90
91 static int open_ended_curve=0;
92 static int n_curve_pts=-1;
93 static int n_palette_colors=-1;
94 static int n_bitmap_pixels=-1;
95 static size_t n_bytes_in_stream=0;
96 static char *byte_stream=NULL;
97 static size_t byte_stream_size=0;
98
99 static kate_float karaoke_base_height=(kate_float)0;
100 static kate_float karaoke_top_height=(kate_float)0;
101
102 typedef struct kd_event {
103 kate_float t0;
104 kate_float t1;
105 kate_float duration;
106 char *text;
107 kate_markup_type text_markup_type;
108 int region_index;
109 const kate_region *region;
110 int style_index;
111 const kate_style *style;
112 int secondary_style_index;
113 const kate_style *secondary_style;
114 int palette_index;
115 const kate_palette *palette;
116 int bitmap_index;
117 const kate_bitmap *bitmap;
118 } kd_event;
119 static kd_event kevent;
120
katedesc_trace(const char * msg,...)121 static void katedesc_trace(const char *msg,...)
122 {
123 va_list ap;
124 va_start(ap,msg);
125 vfprintf(stderr,msg,ap);
126 va_end(ap);
127 }
128 /* #define KDTRACE(msg,args...) katedesc_trace(msg, ##args) */
129 #define KDTRACE katedesc_trace
130
yyerror(const char * s)131 int yyerror(const char *s)
132 {
133 (void)s;
134 KDTRACE("Error line %d: %s (token %s)\n",nlines,s,katedesc_text);
135 nerrors++;
136 return 1;
137 }
138
yyerrorf(const char * msg,...)139 int yyerrorf(const char *msg,...)
140 {
141 static char buffer[4096];
142 va_list ap;
143 va_start(ap,msg);
144 vsnprintf(buffer,sizeof(buffer),msg,ap);
145 buffer[sizeof(buffer)-1]=0;
146 va_end(ap);
147 return yyerror(buffer);
148 }
149
yywarning(const char * s)150 int yywarning(const char *s)
151 {
152 (void)s;
153 KDTRACE("Warning line %d: %s (token %s)\n",nlines,s,katedesc_text);
154 nwarnings++;
155 return 1;
156 }
157
add_meta(kate_meta ** km,const char * tag,const char * value)158 static void add_meta(kate_meta **km,const char *tag,const char *value)
159 {
160 if (!*km) {
161 CHECK_KATE_API_ERROR(kate_meta_create(km));
162 }
163 CHECK_KATE_API_ERROR(kate_meta_add_string(*km,tag,value));
164 }
165
add_meta_byte_stream(kate_meta ** km,const char * tag)166 static void add_meta_byte_stream(kate_meta **km,const char *tag)
167 {
168 if (!*km) {
169 CHECK_KATE_API_ERROR(kate_meta_create(km));
170 }
171 CHECK_KATE_API_ERROR(kate_meta_add(*km,tag,byte_stream,byte_stream_size));
172
173 kate_free(byte_stream);
174 byte_stream=NULL;
175 n_bytes_in_stream=0;
176 byte_stream_size=0;
177 }
178
catstrings(char * s1,const char * s2)179 static char *catstrings(char *s1,const char *s2)
180 {
181 size_t len;
182 char *s;
183
184 if (!s2) { yyerror("internal error: no string to append"); exit(-1); }
185 len=(s1?strlen(s1):0)+strlen(s2)+1;
186 s=(char*)kate_realloc(s1,len);
187 if (!s) { yyerror("out of memory"); exit(-1); }
188 if (s1) strcat(s,s2); else strcpy(s,s2);
189
190 return s;
191 }
192
dupstring(const char * s)193 static char *dupstring(const char *s)
194 {
195 size_t len;
196 char *news;
197
198 if (!s) { yyerror("internal error: no string"); exit(-1); }
199
200 len=strlen(s);
201 news=(char*)kate_malloc(len+1);
202 if (!news) { yyerror("out of memory"); exit(-1); }
203 memcpy(news,s,len+1);
204 return news;
205 }
206
find_item(const char * name,size_t nnames,char ** names)207 static int find_item(const char *name,size_t nnames,char **names)
208 {
209 size_t n;
210 for (n=0;n<nnames;++n) {
211 if (names[n] && !strcmp(names[n],name)) return n;
212 }
213 yyerrorf("Named item not found: %s",name);
214 return 0;
215 }
216
init_palette(void)217 static void init_palette(void)
218 {
219 kpalette.palette=(kate_palette*)kate_malloc(sizeof(kate_palette));
220 if (!kpalette.palette) { yyerror("out of memory"); exit(-1); }
221 if (kate_palette_init(kpalette.palette)<0) {
222 yyerror("palette init failed");
223 exit(-1);
224 }
225 }
226
generate_full_filename(char * full_filename,size_t size,const char * filename)227 static void generate_full_filename(char *full_filename,size_t size,const char *filename)
228 {
229 if (filename[0]=='/' || filename[0]=='\\') {
230 strcpy(full_filename,filename);
231 }
232 else {
233 snprintf(full_filename,size,"%s%s",base_path,filename);
234 full_filename[size-1]=0;
235 }
236 }
237
load_palette(const char * filename)238 static void load_palette(const char *filename)
239 {
240 #ifdef HAVE_PNG
241 int ncolors;
242 kate_color *palette=NULL;
243 static char full_filename[4096];
244
245 generate_full_filename(full_filename,sizeof(full_filename),filename);
246 if (kd_read_png8(full_filename,NULL,NULL,NULL,&palette,&ncolors,NULL)) {
247 yyerrorf("failed to load %s",filename);
248 return;
249 }
250
251 kpalette.palette->ncolors=ncolors;
252 kpalette.palette->colors=palette;
253 #else
254 yyerrorf("PNG support not compiled in: cannot load %s",filename);
255 exit(-1);
256 #endif
257 }
258
check_palette(const kate_palette * kp)259 static void check_palette(const kate_palette *kp)
260 {
261 if (!kp) { yyerror("internal error: no palette"); exit(-1); }
262 }
263
add_palette(kate_info * ki,const char * name,kate_palette * kp)264 static void add_palette(kate_info *ki,const char *name,kate_palette *kp)
265 {
266 int ret;
267
268 check_palette(kp);
269
270 ret=kate_info_add_palette(ki,kp);
271 if (ret<0) {
272 yyerrorf("Failed to register palette: %d",ret);
273 }
274 else {
275 palette_names=(char**)kate_realloc(palette_names,ki->npalettes*sizeof(char*));
276 if (!palette_names) {
277 yyerror("Out of memory");
278 exit(-1);
279 }
280 palette_names[ki->npalettes-1]=name?dupstring(name):NULL;
281 }
282 }
283
find_palette(const kate_info * ki,const char * name)284 static int find_palette(const kate_info *ki,const char *name)
285 {
286 return find_item(name,ki->npalettes,palette_names);
287 }
288
init_bitmap(void)289 static void init_bitmap(void)
290 {
291 kbitmap.bitmap=(kate_bitmap*)kate_malloc(sizeof(kate_bitmap));
292 if (!kbitmap.bitmap) { yyerror("out of memory"); exit(-1); }
293 if (kate_bitmap_init_new(kbitmap.bitmap)<0) {
294 yyerror("bitmap init failed");
295 exit(-1);
296 }
297 }
298
compute_bitmap_x_offset(kate_float percent)299 static int compute_bitmap_x_offset(kate_float percent)
300 {
301 if (kbitmap.bitmap->width) {
302 return (int)(kbitmap.bitmap->width*percent/100+0.5);
303 }
304 else {
305 yyerror("Bitmap width must be known before specifying offset as a percentage");
306 return 0;
307 }
308 }
309
compute_bitmap_y_offset(kate_float percent)310 static int compute_bitmap_y_offset(kate_float percent)
311 {
312 if (kbitmap.bitmap->height) {
313 return (int)(kbitmap.bitmap->height*percent/100+0.5);
314 }
315 else {
316 yyerror("Bitmap height must be known before specifying offset as a percentage");
317 return 0;
318 }
319 }
320
load_bitmap(const char * filename,int paletted)321 static void load_bitmap(const char *filename,int paletted)
322 {
323 #ifdef HAVE_PNG
324 int w,h;
325 unsigned char *pixels=NULL;
326
327 if (paletted) {
328 int bpp;
329 static char full_filename[4096];
330
331 generate_full_filename(full_filename,sizeof(full_filename),filename);
332 if (kd_read_png8(full_filename,&w,&h,&bpp,NULL,NULL,&pixels)) {
333 yyerrorf("failed to load %s",filename);
334 return;
335 }
336
337 kbitmap.bitmap->type=kate_bitmap_type_paletted;
338 kbitmap.bitmap->width=w;
339 kbitmap.bitmap->height=h;
340 kbitmap.bitmap->bpp=bpp;
341 kbitmap.bitmap->pixels=pixels;
342 kbitmap.bitmap->size=0;
343 }
344 else {
345 size_t size;
346 static char full_filename[4096];
347
348 generate_full_filename(full_filename,sizeof(full_filename),filename);
349 if (kd_read_png(full_filename,&w,&h,&pixels,&size)) {
350 yyerrorf("failed to load %s",filename);
351 return;
352 }
353
354 kbitmap.bitmap->type=kate_bitmap_type_png;
355 kbitmap.bitmap->width=w;
356 kbitmap.bitmap->height=h;
357 kbitmap.bitmap->bpp=0;
358 kbitmap.bitmap->pixels=pixels;
359 kbitmap.bitmap->size=size;
360 }
361
362 kbitmap.bitmap->palette=-1;
363 #else
364 (void)paletted;
365 yyerrorf("PNG support not compiled in: cannot load %s",filename);
366 exit(-1);
367 #endif
368 }
369
check_bitmap(const kate_bitmap * kb)370 static void check_bitmap(const kate_bitmap *kb)
371 {
372 if (!kb) { yyerror("internal error: no bitmap"); exit(-1); }
373 }
374
add_bitmap(kate_info * ki,const char * name,kate_bitmap * kb)375 static void add_bitmap(kate_info *ki,const char *name,kate_bitmap *kb)
376 {
377 int ret;
378
379 check_bitmap(kb);
380
381 ret=kate_info_add_bitmap(ki,kb);
382 if (ret<0) {
383 yyerrorf("Failed to register bitmap: %d",ret);
384 }
385 else {
386 bitmap_names=(char**)kate_realloc(bitmap_names,ki->nbitmaps*sizeof(char*));
387 if (!bitmap_names) {
388 yyerror("Out of memory");
389 exit(-1);
390 }
391 bitmap_names[ki->nbitmaps-1]=name?dupstring(name):NULL;
392 }
393 }
394
add_local_bitmap(kate_state * k,const char * name,kate_bitmap * kb)395 static void add_local_bitmap(kate_state *k,const char *name,kate_bitmap *kb)
396 {
397 int ret;
398
399 check_bitmap(kb);
400
401 ret=kate_encode_add_bitmap(k,kb);
402 if (ret<0) {
403 yyerrorf("Failed to register bitmap: %d",ret);
404 }
405 else {
406 ++n_local_bitmaps;
407 local_bitmap_names=(char**)kate_realloc(local_bitmap_names,n_local_bitmaps*sizeof(char*));
408 if (!local_bitmap_names) {
409 yyerror("Out of memory");
410 exit(-1);
411 }
412 local_bitmap_names[n_local_bitmaps-1]=name?dupstring(name):NULL;
413 local_bitmaps=(kate_bitmap**)kate_realloc(local_bitmaps,n_local_bitmaps*sizeof(kate_bitmap*));
414 if (!local_bitmaps) {
415 yyerror("Out of memory");
416 exit(-1);
417 }
418 local_bitmaps[n_local_bitmaps-1]=kb;
419 }
420 }
421
add_local_bitmap_index(kate_state * k,const char * name,size_t idx)422 static void add_local_bitmap_index(kate_state *k,const char *name,size_t idx)
423 {
424 int ret;
425
426 ret=kate_encode_add_bitmap_index(k,idx);
427 if (ret<0) {
428 yyerrorf("Failed to register bitmap: %d",ret);
429 }
430 else {
431 ++n_local_bitmaps;
432 local_bitmap_names=(char**)kate_realloc(local_bitmap_names,n_local_bitmaps*sizeof(char*));
433 if (!local_bitmap_names) {
434 yyerror("Out of memory");
435 exit(-1);
436 }
437 local_bitmap_names[n_local_bitmaps-1]=name?dupstring(name):NULL;
438 local_bitmaps=(kate_bitmap**)kate_realloc(local_bitmaps,n_local_bitmaps*sizeof(kate_bitmap*));
439 if (!local_bitmaps) {
440 yyerror("Out of memory");
441 exit(-1);
442 }
443 local_bitmaps[n_local_bitmaps-1]=NULL;
444 }
445 }
446
find_bitmap(const kate_info * ki,const char * name)447 static int find_bitmap(const kate_info *ki,const char *name)
448 {
449 int ret=find_item(name,ki->nbitmaps,bitmap_names);
450 if (ret>=0) return ret;
451 ret=find_item(name,n_local_bitmaps,local_bitmap_names);
452 if (ret>=0) return ret+ki->nbitmaps;
453 return ret;
454 }
455
check_style(const kate_style * ks)456 static void check_style(const kate_style *ks)
457 {
458 if (!ks) { yyerror("internal error: no style"); exit(-1); }
459 }
460
add_style(kate_info * ki,const char * name,const kate_style * ks)461 static void add_style(kate_info *ki,const char *name,const kate_style *ks)
462 {
463 int ret;
464 kate_style *ks2;
465
466 check_style(ks);
467
468 ks2=(kate_style*)kate_malloc(sizeof(*ks2));
469 if (!ks2) {
470 yyerrorf("Out of memory");
471 exit(-1);
472 }
473 memcpy(ks2,ks,sizeof(*ks2));
474
475 ret=kate_info_add_style(ki,ks2);
476 if (ret<0) {
477 yyerrorf("Failed to register style: %d",ret);
478 }
479 else {
480 style_names=(char**)kate_realloc(style_names,ki->nstyles*sizeof(char*));
481 if (!style_names) {
482 yyerror("Out of memory");
483 exit(-1);
484 }
485 style_names[ki->nstyles-1]=name?dupstring(name):NULL;
486 }
487 }
488
find_style(const kate_info * ki,const char * name)489 static int find_style(const kate_info *ki,const char *name)
490 {
491 return find_item(name,ki->nstyles,style_names);
492 }
493
check_region(const kate_region * kr)494 static void check_region(const kate_region *kr)
495 {
496 if (!kr) { yyerror("internal error: no region"); exit(-1); }
497 if (kr->w<0) yyerrorf("Region width (%d) must be non negative",kr->w);
498 if (kr->h<0) yyerrorf("Region height (%d) must be non negative",kr->h);
499 }
500
add_region(kate_info * ki,const char * name,const kate_region * kr)501 static void add_region(kate_info *ki,const char *name,const kate_region *kr)
502 {
503 int ret;
504 kate_region *kr2;
505
506 check_region(kr);
507
508 kr2=(kate_region*)kate_malloc(sizeof(*kr2));
509 if (!kr2) {
510 yyerrorf("Out of memory");
511 exit(-1);
512 }
513 memcpy(kr2,kr,sizeof(*kr2));
514
515 ret=kate_info_add_region(ki,kr2);
516 if (ret<0) {
517 yyerrorf("Failed to register region: %d",ret);
518 }
519 else {
520 region_names=(char**)kate_realloc(region_names,ki->nregions*sizeof(char*));
521 if (!region_names) {
522 yyerror("Out of memory");
523 exit(-1);
524 }
525 region_names[ki->nregions-1]=name?dupstring(name):NULL;
526 }
527 }
528
find_region(const kate_info * ki,const char * name)529 static int find_region(const kate_info *ki,const char *name)
530 {
531 return find_item(name,ki->nregions,region_names);
532 }
533
check_curve(const kate_curve * kc)534 static void check_curve(const kate_curve *kc)
535 {
536 size_t minpts=0,maxpts=INT_MAX;
537 if (!kc) { yyerror("internal error: no curve"); exit(-1); }
538 switch (kc->type) {
539 case kate_curve_none: minpts=0; maxpts=0; break;
540 case kate_curve_static: minpts=1; maxpts=1; break;
541 case kate_curve_linear: minpts=2; maxpts=INT_MAX; break;
542 case kate_curve_catmull_rom_spline: minpts=2; maxpts=INT_MAX; break;
543 case kate_curve_bezier_cubic_spline: minpts=3; maxpts=INT_MAX; break;
544 case kate_curve_bspline: minpts=2; maxpts=INT_MAX; break;
545 }
546 if (kc->npts<minpts) yyerrorf("Curve does not have enough points for this type (has %d, min pts %d)",kc->npts,minpts);
547 if (kc->npts>maxpts) yyerrorf("Curve has too many points for this type (has %d, max pts %d)",kc->npts,maxpts);
548 if (kc->type==kate_curve_bezier_cubic_spline) {
549 if ((kc->npts-1)%3) yyerrorf("Cubic Bezier splines should have 1+3n points");
550 }
551 }
552
add_curve(kate_info * ki,const char * name,kate_curve * kc)553 static void add_curve(kate_info *ki,const char *name,kate_curve *kc)
554 {
555 int ret;
556
557 check_curve(kc);
558
559 ret=kate_info_add_curve(ki,kc);
560 if (ret<0) {
561 yyerrorf("Failed to register curve: %d",ret);
562 }
563 else {
564 curve_names=(char**)kate_realloc(curve_names,ki->ncurves*sizeof(char*));
565 if (!curve_names) {
566 yyerror("Out of memory");
567 exit(-1);
568 }
569 curve_names[ki->ncurves-1]=name?dupstring(name):NULL;
570 }
571 }
572
find_curve(const kate_info * ki,const char * name)573 static int find_curve(const kate_info *ki,const char *name)
574 {
575 return find_item(name,ki->ncurves,curve_names);
576 }
577
clear_motions(void)578 static void clear_motions(void)
579 {
580 kate_free(kmotions);
581 kmotions=NULL;
582 kmotion=NULL;
583 nkmotions=0;
584 }
585
check_motion(kate_motion * kmotion)586 static void check_motion(kate_motion *kmotion)
587 {
588 if (!kmotion) { yyerror("internal error: no motion"); exit(-1); }
589
590 if (kmotion->ncurves==0) { yyerror("motion must have at least one curve"); return; }
591 if (kmotion->semantics==(kate_motion_semantics)-1) { yyerror("motion semantics is not defined"); return; }
592 }
593
add_motion(kate_info * ki,const char * name,kate_motion * km)594 static void add_motion(kate_info *ki,const char *name,kate_motion *km)
595 {
596 int ret;
597
598 check_motion(km);
599
600 ret=kate_info_add_motion(ki,km);
601 if (ret<0) {
602 yyerrorf("Failed to register motion: %d",ret);
603 }
604 else {
605 motion_names=(char**)kate_realloc(motion_names,ki->nmotions*sizeof(char*));
606 if (!motion_names) {
607 yyerror("Out of memory");
608 exit(-1);
609 }
610 motion_names[ki->nmotions-1]=name?dupstring(name):NULL;
611 }
612
613 clear_motions();
614 }
615
find_motion(const kate_info * ki,const char * name)616 static int find_motion(const kate_info *ki,const char *name)
617 {
618 return find_item(name,ki->nmotions,motion_names);
619 }
620
init_style(kd_style * style)621 static void init_style(kd_style *style)
622 {
623 int ret=kate_style_init(style);
624 if (ret<0) {
625 yyerrorf("Error initializing style: %d\n",ret);
626 exit(1);
627 }
628 }
629
set_font_width(kd_style * style,kate_float s,kate_space_metric metric)630 static void set_font_width(kd_style *style,kate_float s,kate_space_metric metric)
631 {
632 if (style->font_width>=0) {
633 yyerror("Font width already set");
634 }
635 if (style->font_height>=0 && style->font_metric!=metric) {
636 yyerror("All font size metrics must be the same");
637 }
638 style->font_width=s;
639 style->font_metric=metric;
640 }
641
set_font_height(kd_style * style,kate_float s,kate_space_metric metric)642 static void set_font_height(kd_style *style,kate_float s,kate_space_metric metric)
643 {
644 if (style->font_height>=0) {
645 yyerror("Font height already set");
646 }
647 if (style->font_width>=0 && style->font_metric!=metric) {
648 yyerror("All font size metrics must be the same");
649 }
650 style->font_height=s;
651 style->font_metric=metric;
652 }
653
set_font(kd_style * style,const char * font)654 static void set_font(kd_style *style,const char *font)
655 {
656 size_t len;
657 if (!font) {
658 yyerror("Internal error: no font");
659 exit(-1);
660 }
661 len=strlen(font);
662 if (style->font) {
663 yyerror("Font already set");
664 }
665 style->font=(char*)kate_malloc(len+1);
666 if (!style->font) {
667 yyerror("out of memory");
668 exit(-1);
669 }
670 strcpy(style->font,font);
671 }
672
set_font_size(kd_style * style,kate_float s,kate_space_metric metric)673 static void set_font_size(kd_style *style,kate_float s,kate_space_metric metric)
674 {
675 if (style->font_height>=0 || style->font_width>=0) {
676 yyerror("Font width and/or height already set");
677 }
678 style->font_width=s;
679 style->font_height=s;
680 style->font_metric=metric;
681 }
682
set_margin(kd_style * style,kate_float * margin,kate_float m,kate_space_metric metric)683 static void set_margin(kd_style *style,kate_float *margin,kate_float m,kate_space_metric metric)
684 {
685 int metric_already_set=0;
686 if (&style->left_margin!=margin && style->left_margin!=0) metric_already_set=1;
687 if (&style->top_margin!=margin && style->top_margin!=0) metric_already_set=1;
688 if (&style->right_margin!=margin && style->right_margin!=0) metric_already_set=1;
689 if (&style->bottom_margin!=margin && style->bottom_margin!=0) metric_already_set=1;
690 if (metric_already_set && metric!=style->margin_metric) {
691 yyerror("Metric must be the same for all margins");
692 return;
693 }
694 *margin=m;
695 style->margin_metric=metric;
696 }
697
set_margins(kd_style * style,kate_float left,kate_space_metric left_metric,kate_float top,kate_space_metric top_metric,kate_float right,kate_space_metric right_metric,kate_float bottom,kate_space_metric bottom_metric)698 static void set_margins(kd_style *style,
699 kate_float left,kate_space_metric left_metric,
700 kate_float top,kate_space_metric top_metric,
701 kate_float right,kate_space_metric right_metric,
702 kate_float bottom,kate_space_metric bottom_metric)
703 {
704 if (left_metric!=right_metric || left_metric!=top_metric || left_metric!=bottom_metric) {
705 yyerror("Metric must be the same for all margins");
706 return;
707 }
708 style->left_margin=left;
709 style->top_margin=top;
710 style->right_margin=right;
711 style->bottom_margin=bottom;
712 style->margin_metric=left_metric;
713 }
714
init_style_from(int idx)715 static void init_style_from(int idx)
716 {
717 const kate_style *from=ki.styles[idx];
718 init_style(&kstyle);
719 memcpy(&kstyle,from,sizeof(kate_style));
720 }
721
init_region(kd_region * region)722 static void init_region(kd_region *region)
723 {
724 int ret=kate_region_init(region);
725 if (ret<0) {
726 yyerrorf("Error initializing region: %d\n",ret);
727 exit(1);
728 }
729 }
730
init_region_from(int idx)731 static void init_region_from(int idx)
732 {
733 const kate_region *from=ki.regions[idx];
734 init_region(&kregion);
735 memcpy(&kregion,from,sizeof(kate_region));
736 }
737
reference_curve_from(int idx)738 static void reference_curve_from(int idx)
739 {
740 kcurve.idx=idx;
741 kcurve.curve=NULL;
742 }
743
init_curve(void)744 static void init_curve(void)
745 {
746 kcurve.idx=0;
747 kcurve.curve=(kate_curve*)kate_malloc(sizeof(kate_curve));
748 if (!kcurve.curve) { yyerror("out of memory"); exit(-1); }
749 if (kate_curve_init(kcurve.curve)<0) {
750 yyerror("error initializing curve");
751 exit(-1);
752 }
753 }
754
init_curve_from(int idx)755 static void init_curve_from(int idx)
756 {
757 const kate_curve *from=ki.curves[idx];
758 if (!from || !from->pts) {
759 yyerror("invalid curve to init from");
760 exit(-1);
761 }
762 init_curve();
763 memcpy(kcurve.curve,from,sizeof(kate_curve));
764 kcurve.curve->pts=(kate_float*)kate_malloc(kcurve.curve->npts*2*sizeof(kate_float));
765 if (!kcurve.curve->pts) {
766 yyerror("out of memory");
767 exit(-1);
768 }
769 memcpy(kcurve.curve->pts,from->pts,kcurve.curve->npts*2*sizeof(kate_float));
770 }
771
init_curve_points(int npts)772 static void init_curve_points(int npts)
773 {
774 if (!kcurve.curve) { yyerror("internal error: curve not initialized"); exit(-1); }
775 if (n_curve_pts<0) { katedesc_error("Curve type must be specified before the points"); exit(-1); }
776 if (npts<=0) { katedesc_error("Number of points cannot be negative or zero"); exit(-1); }
777 kcurve.curve->npts=npts;
778 kcurve.curve->pts=(kate_float*)kate_malloc(npts*2*sizeof(kate_float));
779 if (!kcurve.curve->pts) {
780 yyerror("Out of memory");
781 exit(-1);
782 }
783 open_ended_curve=0;
784 }
785
init_open_ended_curve_points(void)786 static void init_open_ended_curve_points(void)
787 {
788 if (!kcurve.curve) { yyerror("internal error: curve not initialized"); exit(-1); }
789 if (n_curve_pts<0) katedesc_error("Curve type must be specified before the points");
790 kcurve.curve->npts=0;
791 kcurve.curve->pts=NULL;
792 open_ended_curve=1;
793 }
794
add_open_ended_curve_point(kate_float pt)795 static void add_open_ended_curve_point(kate_float pt)
796 {
797 if (!kcurve.curve) { yyerror("internal error: curve not initialized"); exit(-1); }
798 ++n_curve_pts;
799 kcurve.curve->npts=(n_curve_pts+1)/2;
800 kcurve.curve->pts=(kate_float*)kate_realloc(kcurve.curve->pts,kcurve.curve->npts*2*sizeof(kate_float));
801 if (!kcurve.curve->pts) {
802 yyerror("Out of memory");
803 exit(-1);
804 }
805 kcurve.curve->pts[n_curve_pts-1]=pt;
806 }
807
init_palette_colors(int ncolors)808 static void init_palette_colors(int ncolors)
809 {
810 if (!kpalette.palette) { yyerror("internal error: palette not initialized"); exit(-1); }
811 kpalette.palette->ncolors=ncolors;
812 kpalette.palette->colors=(kate_color*)kate_malloc(ncolors*sizeof(kate_color));
813 if (!kpalette.palette->colors) {
814 yyerror("Out of memory");
815 exit(-1);
816 }
817 n_palette_colors=0;
818 }
819
init_bitmap_pixels(int width,int height,int bpp)820 static void init_bitmap_pixels(int width,int height,int bpp)
821 {
822 if (!kbitmap.bitmap) { yyerror("internal error: bitmap not initialized"); exit(-1); }
823 if (width<=0 || height<=0) yyerror("Bitmap dimensions must be positive");
824 if (bpp<=0) yyerror("Bitmap bit depth must be positive");
825 if (bpp>8) yyerrorf("Bitmap bit depth must not be more than 8 (is %d)",bpp);
826 kbitmap.bitmap->type=kate_bitmap_type_paletted;
827 kbitmap.bitmap->width=width;
828 kbitmap.bitmap->height=height;
829 kbitmap.bitmap->bpp=bpp;
830 kbitmap.bitmap->pixels=(unsigned char*)kate_malloc(width*height*sizeof(unsigned char));
831 if (!kbitmap.bitmap->pixels) {
832 yyerror("Out of memory");
833 exit(-1);
834 }
835 kbitmap.bitmap->size=0;
836 n_bitmap_pixels=0;
837 }
838
init_png_bitmap_pixels(int width,int height,int size)839 static void init_png_bitmap_pixels(int width,int height,int size)
840 {
841 if (!kbitmap.bitmap) { yyerror("internal error: bitmap not initialized"); exit(-1); }
842 if (width<=0 || height<=0) yyerror("Bitmap dimensions must be positive");
843 kbitmap.bitmap->type=kate_bitmap_type_png;
844 kbitmap.bitmap->width=width;
845 kbitmap.bitmap->height=height;
846 kbitmap.bitmap->bpp=0;
847 kbitmap.bitmap->pixels=(unsigned char*)kate_malloc(size);
848 if (!kbitmap.bitmap->pixels) {
849 yyerror("Out of memory");
850 exit(-1);
851 }
852 kbitmap.bitmap->size=size;
853 n_bitmap_pixels=0;
854 }
855
init_byte_stream(int nbytes)856 static void init_byte_stream(int nbytes)
857 {
858 if (nbytes<0) { yyerror("internal error: negative number of bytes"); exit(-1); }
859 byte_stream=(char*)kate_malloc(nbytes);
860 if (!byte_stream) {
861 yyerror("Out of memory");
862 exit(-1);
863 }
864 n_bytes_in_stream=0;
865 byte_stream_size=nbytes;
866 }
867
set_color(kate_color * kc,uint32_t c)868 static void set_color(kate_color *kc,uint32_t c)
869 {
870 int r=(c>>24)&0xff;
871 int g=(c>>16)&0xff;
872 int b=(c>>8)&0xff;
873 int a=(c>>0)&0xff;
874 if (!kc) {
875 yyerror("Internal error: null color");
876 exit(-1);
877 }
878 if (r<0 || r>255) yyerrorf("red component (%d) must be between 0 and 255",r);
879 if (g<0 || g>255) yyerrorf("green component (%d) must be between 0 and 255",g);
880 if (b<0 || b>255) yyerrorf("blue component (%d) must be between 0 and 255",b);
881 if (a<0 || a>255) yyerrorf("alpha component (%d) must be between 0 and 255",a);
882 kc->r=r;
883 kc->g=g;
884 kc->b=b;
885 kc->a=a;
886 }
887
init_event(kd_event * ev)888 static void init_event(kd_event *ev)
889 {
890 if (!ev) {
891 yyerror("Internal error: null event");
892 exit(-1);
893 }
894 ev->t0=ev->t1=ev->duration=(kate_float)-1.0;
895 ev->text=NULL;
896 ev->text_markup_type=kate_markup_none;
897 ev->region_index=ev->style_index=ev->secondary_style_index=-1;
898 ev->region=NULL;
899 ev->style=NULL;
900 ev->secondary_style=NULL;
901 ev->palette_index=ev->bitmap_index=-1;
902 ev->palette=NULL;
903 ev->bitmap=NULL;
904 }
905
kd_encode_set_id(kate_state * kstate,unsigned int id)906 static void kd_encode_set_id(kate_state *kstate,unsigned int id)
907 {
908 if (id&0x80000000) yyerrorf("ID %d (hex %x) out of range, must fit on 31 bits",id,id);
909
910 /* unused at the moment - will need to map an autogenerated id to this user id */
911 (void)kstate;
912 (void)id;
913 }
914
add_entity(const char * entity,char ** text,size_t * wlen0)915 static int add_entity(const char *entity,char **text,size_t *wlen0)
916 {
917 int count=0;
918
919 if (!entity || !text || !wlen0) {
920 yyerror("internal error: add_entity passed null parameter");
921 exit(-1);
922 }
923
924 /* write out the entity */
925 while (*entity) {
926 int ret=kate_text_set_character(kate_utf8,*entity,text,wlen0);
927 if (ret<0) return ret;
928 count+=ret;
929 ++entity;
930 }
931 return count;
932 }
933
expand_numeric_entities(const char * text)934 static char *expand_numeric_entities(const char *text)
935 {
936 enum {
937 s_text,
938 s_amp,
939 s_code,
940 s_named
941 } state=s_text;
942 int c,code=0,code_from_numeric,base=-1;
943 size_t len=strlen(text),len0=len+1,rlen0=len0,wlen0=len0,allocated=len0;
944 /* we might need to replace "�" with "&" - we can't use more characters, so we needn't allocate more */
945 /* this might change if we even can replace a numeric entity with a named one that is longer as a string */
946 char *newtext=(char*)kate_malloc(allocated),*newtextptr=newtext;
947
948 if (!newtext) { yyerror("out of memory"); exit(-1); }
949
950 while (1) {
951 int ret=kate_text_get_character(kate_utf8,&text,&rlen0);
952 if (ret<0) {
953 yyerrorf("failed to read character: %d",ret);
954 kate_free(newtext);
955 return NULL;
956 }
957 c=ret;
958
959 code_from_numeric=0;
960 switch (state) {
961 case s_text:
962 if (c=='&') {
963 state=s_amp;
964 code=0;
965 }
966 break;
967 case s_amp:
968 if (c=='#') {
969 state=s_code;
970 base=-1; /* unknown yet */
971 }
972 else {
973 state=s_named;
974
975 /* we've encountered a named entity, and we've discarded the & already,
976 so we need to add it now before the newly read character */
977 ret=kate_text_set_character(kate_utf8,'&',&newtextptr,&wlen0);
978 if (ret<0) {
979 yyerrorf("failed to write character: %d",ret);
980 kate_free(newtext);
981 return NULL;
982 }
983 }
984 break;
985 case s_code:
986 if (c==';') {
987 if (base<0) {
988 /* no code given */
989 yyerrorf("no code given in numeric entity");
990 c=0;
991 code_from_numeric=1;
992 state=s_text;
993 }
994 else {
995 c=code; /* this will be written below */
996 code_from_numeric=1;
997 state=s_text;
998 }
999 }
1000 else {
1001 /* if first character, determine if this is decimal or hexadecimal */
1002 if (base<0) {
1003 if (c=='x' || c=='X') {
1004 base=16;
1005 break; /* the code starts next character */
1006 }
1007 else {
1008 base=10;
1009 /* fall through */
1010 }
1011 }
1012
1013 code*=base;
1014 if (isdigit(c)) code+=(c-'0');
1015 else if (base==16 && isxdigit(c)) code+=(tolower(c)-'a'+10);
1016 else yyerrorf("invalid character in numeric entity (only numeric entities are supported), got %d",c);
1017 }
1018 break;
1019 case s_named:
1020 if (c==';') {
1021 state=s_text;
1022 }
1023 break;
1024 }
1025
1026 if (state==s_text || state==s_named) {
1027 /* we don't want to expand characters in "<&>" as they would then be wrongly interpreted,
1028 so we insert here as entities - note that we don't want to expand them and do another
1029 pass to reencode them, as we then might pick up others that *were* in the text verbatim */
1030 if (code_from_numeric && (c&~0xff)==0 && strchr("<&>",c)) {
1031 switch (c) {
1032 case '<': ret=add_entity("<",&newtextptr,&wlen0); break;
1033 case '&': ret=add_entity("&",&newtextptr,&wlen0); break;
1034 case '>': ret=add_entity(">",&newtextptr,&wlen0); break;
1035 }
1036 }
1037 else {
1038 ret=kate_text_set_character(kate_utf8,c,&newtextptr,&wlen0);
1039 }
1040 if (ret<0) {
1041 yyerrorf("failed to write character: %d",ret);
1042 kate_free(newtext);
1043 return NULL;
1044 }
1045 }
1046 if (c==0) break;
1047 }
1048 return newtext;
1049 }
1050
getrawline(const char ** text)1051 static char *getrawline(const char **text)
1052 {
1053 size_t rlen0;
1054 int newline,in_newline=0;
1055 const char *start_of_line;
1056 int c;
1057
1058 if (!text || !*text) {
1059 yyerror("error: getrawline passed invalid text pointer");
1060 exit(-1);
1061 }
1062
1063 rlen0=strlen(*text)+1;
1064 start_of_line=*text;
1065
1066 while (1) {
1067 const char *ptr=*text;
1068 int ret=kate_text_get_character(kate_utf8,text,&rlen0);
1069 if (ret<0) {
1070 yyerrorf("failed to read character: %d",ret);
1071 return NULL;
1072 }
1073 c=ret;
1074 if (c==0) {
1075 /* end of the string, return everything */
1076 size_t len=strlen(start_of_line);
1077 char *line=(char*)kate_malloc(len+1);
1078 memcpy(line,start_of_line,len+1);
1079 *text=ptr; /* do not push past the start of the new line */
1080 return line;
1081 }
1082 newline=(c=='\r' || c=='\n');
1083 if (!newline && in_newline) {
1084 /* we are at the start of a new line */
1085 char *line=(char*)kate_malloc(ptr-start_of_line+1);
1086 memcpy(line,start_of_line,ptr-start_of_line);
1087 line[ptr-start_of_line]=0;
1088 *text=ptr; /* do not push past the start of the new line */
1089 return line;
1090 }
1091 in_newline=newline;
1092 }
1093 }
1094
trimend(char * line,size_t rlen0,int * eol)1095 static void trimend(char *line,size_t rlen0,int *eol)
1096 {
1097 int ret;
1098 int c;
1099 int ws;
1100 char *text=line;
1101
1102 if (!line) return;
1103
1104 ret=kate_text_get_character(kate_utf8,(const char**)&text,&rlen0);
1105 if (ret<0) {
1106 yyerrorf("failed to read character: %d",ret);
1107 return;
1108 }
1109 c=ret;
1110 if (c==0) {
1111 *eol=1;
1112 return;
1113 }
1114
1115 trimend(text,rlen0,eol);
1116
1117 ws=((c<=0xff) && (strchr(" \t\n\r",c)!=NULL));
1118 if (*eol && ws) *line=0;
1119 if (!ws) *eol=0;
1120 }
1121
trimline(const char * line)1122 static char *trimline(const char *line)
1123 {
1124 char *trimmed;
1125 size_t rlen0;
1126 int c;
1127 int eol=0;
1128
1129 if (!line) {
1130 yyerror("error: trimline passed null line");
1131 exit(-1);
1132 }
1133
1134 rlen0=strlen(line)+1;
1135
1136 /* first seek to the first non whitespace character in the line */
1137 while (1) {
1138 const char *ptr=line;
1139 int ret=kate_text_get_character(kate_utf8,&ptr,&rlen0);
1140 if (ret<0) {
1141 yyerrorf("failed to read character: %d",ret);
1142 return NULL;
1143 }
1144 c=ret;
1145 if (!c || (c!=' ' && c!='\t')) {
1146 /* we found a non whitespace, or an end of line, stop */
1147 break;
1148 }
1149 /* we can advance the start of the line */
1150 line=ptr;
1151 }
1152
1153 rlen0=strlen(line)+1;
1154 trimmed=(char*)kate_malloc(rlen0);
1155 memcpy(trimmed,line,rlen0);
1156 trimend(trimmed,strlen(trimmed)+1,&eol);
1157 return trimmed;
1158 }
1159
trimtext(const char * text)1160 static char *trimtext(const char *text)
1161 {
1162 char *newtext=(char*)kate_malloc(1);
1163 *newtext=0;
1164 while (text && *text) {
1165 char *line=getrawline(&text);
1166 char *trimmed=trimline(line);
1167 kate_free(line);
1168 if (*trimmed && strcmp(trimmed,"\n")) {
1169 /* ignore empty lines */
1170 if (newtext && *newtext) {
1171 /* add a newline between lines (eg, not before the first line) */
1172 newtext=catstrings(newtext,"\n");
1173 }
1174 newtext=catstrings(newtext,trimmed);
1175 }
1176 kate_free(trimmed);
1177 }
1178 return newtext;
1179 }
1180
trimtext_pre(const char * text)1181 static char *trimtext_pre(const char *text)
1182 {
1183 /* in pre, we just kill a new line at start and one at the end, if any */
1184 size_t len;
1185 char *newtext;
1186
1187 if (!text) {
1188 yyerror("error: trimtext_pre passed null text");
1189 exit(-1);
1190 }
1191
1192 len=strlen(text);
1193 newtext=(char*)kate_malloc(len+1);
1194
1195 /* start */
1196 if (*text=='\n') {
1197 memcpy(newtext,text+1,len);
1198 --len;
1199 }
1200 else {
1201 memcpy(newtext,text,len+1);
1202 }
1203
1204 /* end */
1205 if (len>0 && newtext[len-1]=='\n') {
1206 newtext[len-1]=0;
1207 }
1208
1209 return newtext;
1210 }
1211
backslash_n_to_newline(char * text)1212 static void backslash_n_to_newline(char *text)
1213 {
1214 char *ptr=text;
1215 while (ptr && (ptr=strstr(ptr,"\\n"))) {
1216 *ptr='\n';
1217 memmove(ptr+1,ptr+2,strlen(ptr+2)+1);
1218 }
1219 }
1220
set_event_text(kd_event * ev,const char * text,int pre,int markup)1221 static void set_event_text(kd_event *ev,const char *text,int pre,int markup)
1222 {
1223 char *newtext,*expanded;
1224 size_t len;
1225
1226 if (ev->text) {
1227 yyerrorf("text already set (to %s, trying to set to %s)",ev->text,text);
1228 return;
1229 }
1230 if (!text) {
1231 yyerror("null text");
1232 return;
1233 }
1234
1235 len=strlen(text);
1236 newtext=(char*)kate_malloc(len+1);
1237 memcpy(newtext,text,len+1);
1238 backslash_n_to_newline(newtext);
1239
1240 expanded=expand_numeric_entities(newtext);
1241 kate_free(newtext);
1242 newtext=expanded;
1243
1244 if (!pre) {
1245 char *trimmed_newtext=trimtext(newtext);
1246 kate_free(newtext);
1247 newtext=trimmed_newtext;
1248 }
1249 else {
1250 char *trimmed_newtext=trimtext_pre(newtext);
1251 kate_free(newtext);
1252 newtext=trimmed_newtext;
1253 }
1254
1255 if (markup) {
1256 ev->text_markup_type=kate_markup_simple;
1257 }
1258 else {
1259 ev->text_markup_type=kate_markup_none;
1260 }
1261
1262 ev->text=newtext;
1263 }
1264
set_event_text_from(kd_event * ev,const char * source,int pre,int markup)1265 static void set_event_text_from(kd_event *ev,const char *source,int pre,int markup)
1266 {
1267 FILE *f;
1268 char *text=NULL;
1269 char s[4096],*sret;
1270
1271 f=fopen(source,"rt");
1272 if (!f) {
1273 yyerrorf("Failed to open file %s\n",source);
1274 exit(-1);
1275 }
1276 sret=fgets(s,sizeof(s),f);
1277 if (!sret) {
1278 yyerrorf("Failed to read from file %s\n",source);
1279 exit(-1);
1280 }
1281 while (!feof(f)) {
1282 /* This implicitely forbids embedded zeros - could this be a problem ? */
1283 text=catstrings(text,s);
1284 sret=fgets(s,sizeof(s),f);
1285 if (!sret) {
1286 yyerrorf("Failed to read from file %s\n",source);
1287 exit(-1);
1288 }
1289 }
1290 fclose(f);
1291
1292 if (text) {
1293 set_event_text(ev,text,pre,markup);
1294 kate_free(text);
1295 }
1296 }
1297
set_event_t0_t1(kd_event * ev,kate_float t0,kate_float t1)1298 static void set_event_t0_t1(kd_event *ev,kate_float t0,kate_float t1)
1299 {
1300 if (ev->t0>=0) { yyerror("start time already set"); return; }
1301 if (ev->t1>=0) { yyerror("end time already set"); return; }
1302 ev->t0=t0;
1303 ev->t1=t1;
1304 }
1305
set_event_t0(kd_event * ev,kate_float v)1306 static void set_event_t0(kd_event *ev,kate_float v)
1307 {
1308 if (ev->t0>=0) { yyerror("start time already set"); return; }
1309 ev->t0=v;
1310 }
1311
set_event_t1(kd_event * ev,kate_float v)1312 static void set_event_t1(kd_event *ev,kate_float v)
1313 {
1314 if (ev->t1>=0) { yyerror("end time already set"); return; }
1315 ev->t1=v;
1316 }
1317
set_event_duration(kd_event * ev,kate_float v)1318 static void set_event_duration(kd_event *ev,kate_float v)
1319 {
1320 if (ev->duration>=0) { yyerror("duration already set"); return; }
1321 ev->duration=v;
1322 }
1323
set_event_region_index(kd_event * ev,int r)1324 static void set_event_region_index(kd_event *ev,int r)
1325 {
1326 int ret;
1327 if (ev->region_index>=0 || ev->region) { yyerror("region already set"); return; }
1328 ev->region_index=r;
1329 ret=kate_encode_set_region_index(&k,r);
1330 if (ret<0) yyerrorf("failed to set region index: %d",ret);
1331 }
1332
set_event_region(kd_event * ev,kate_region * kr)1333 static void set_event_region(kd_event *ev,kate_region *kr)
1334 {
1335 int ret;
1336 check_region(kr);
1337 if (ev->region_index>=0 || ev->region) { yyerror("region already set"); return; }
1338 ev->region=kr;
1339 ret=kate_encode_set_region(&k,kr);
1340 if (ret<0) yyerrorf("failed to set region: %d",ret);
1341 }
1342
set_event_style_index(kd_event * ev,int s)1343 static void set_event_style_index(kd_event *ev,int s)
1344 {
1345 int ret;
1346 if (ev->style_index>=0 || ev->style) { yyerror("style already set"); return; }
1347 ev->style_index=s;
1348 ret=kate_encode_set_style_index(&k,s);
1349 if (ret<0) yyerrorf("failed to set style index: %d",ret);
1350 }
1351
set_event_secondary_style_index(kd_event * ev,int s)1352 static void set_event_secondary_style_index(kd_event *ev,int s)
1353 {
1354 int ret;
1355 if (ev->secondary_style_index>=0 || ev->secondary_style) { yyerror("secondary style already set"); return; }
1356 ev->secondary_style_index=s;
1357 ret=kate_encode_set_secondary_style_index(&k,s);
1358 if (ret<0) yyerrorf("failed to set secondary style index: %d",ret);
1359 }
1360
set_event_style(kd_event * ev,kate_style * ks)1361 static void set_event_style(kd_event *ev,kate_style *ks)
1362 {
1363 int ret;
1364 check_style(ks);
1365 if (ev->style_index>=0 || ev->style) { yyerror("style already set"); return; }
1366 ev->style=ks;
1367 ret=kate_encode_set_style(&k,ks);
1368 if (ret<0) yyerrorf("failed to set style: %d",ret);
1369 }
1370
set_event_secondary_style(kd_event * ev,kate_style * ks)1371 static void set_event_secondary_style(kd_event *ev,kate_style *ks)
1372 {
1373 int ret;
1374 check_style(ks);
1375 if (ev->secondary_style_index>=0 || ev->secondary_style) { yyerror("secondary style already set"); return; }
1376 ev->secondary_style=ks;
1377 ret=kate_encode_set_secondary_style(&k,ks);
1378 if (ret<0) yyerrorf("failed to set secondary style: %d",ret);
1379 }
1380
set_event_palette_index(kd_event * ev,int p)1381 static void set_event_palette_index(kd_event *ev,int p)
1382 {
1383 int ret;
1384 if (ev->palette_index>=0 || ev->palette) { yyerror("palette already set"); return; }
1385 ev->palette_index=p;
1386 ret=kate_encode_set_palette_index(&k,p);
1387 if (ret<0) yyerrorf("failed to set palette index: %d",ret);
1388 }
1389
set_event_palette(kd_event * ev,kate_palette * kp)1390 static void set_event_palette(kd_event *ev,kate_palette *kp)
1391 {
1392 int ret;
1393 check_palette(kp);
1394 if (ev->palette_index>=0 || ev->palette) { yyerror("palette already set"); return; }
1395 ev->palette=kp;
1396 ret=kate_encode_set_palette(&k,kp);
1397 if (ret<0) yyerrorf("failed to set palette: %d",ret);
1398 }
1399
set_event_bitmap_index(kd_event * ev,int b)1400 static void set_event_bitmap_index(kd_event *ev,int b)
1401 {
1402 int ret;
1403 if (ev->bitmap_index>=0 || ev->bitmap) { yyerror("bitmap already set"); return; }
1404 ev->bitmap_index=b;
1405 ret=kate_encode_set_bitmap_index(&k,b);
1406 if (ret<0) yyerrorf("failed to set bitmap index: %d",ret);
1407 }
1408
set_event_bitmap(kd_event * ev,kate_bitmap * kb)1409 static void set_event_bitmap(kd_event *ev,kate_bitmap *kb)
1410 {
1411 int ret;
1412 check_bitmap(kb);
1413 if (ev->bitmap_index>=0 || ev->bitmap) { yyerror("bitmap already set"); return; }
1414 ev->bitmap=kb;
1415 ret=kate_encode_set_bitmap(&k,kb);
1416 if (ret<0) yyerrorf("failed to set bitmap: %d",ret);
1417 }
1418
kd_add_event_meta(const char * tag,const char * value)1419 static void kd_add_event_meta(const char *tag,const char *value)
1420 {
1421 kate_meta *meta;
1422 int ret;
1423
1424 ret=kate_meta_create(&meta);
1425 if (ret>=0) {
1426 ret=kate_meta_add_string(meta,tag,value);
1427 if (ret>=0) {
1428 ret=kate_encode_merge_meta(&k,meta);
1429 if (ret<0) {
1430 kate_meta_destroy(meta);
1431 }
1432 }
1433 else {
1434 kate_meta_destroy(meta);
1435 }
1436 }
1437 if (ret<0) yyerrorf("failed to add metadata: %d",ret);
1438 }
1439
kd_add_event_meta_byte_stream(const char * tag)1440 static void kd_add_event_meta_byte_stream(const char *tag)
1441 {
1442 kate_meta *meta;
1443 int ret;
1444
1445 ret=kate_meta_create(&meta);
1446 if (ret>=0) {
1447 ret=kate_meta_add(meta,tag,byte_stream,byte_stream_size);
1448 if (ret>=0) {
1449 ret=kate_encode_merge_meta(&k,meta);
1450 if (ret<0) {
1451 kate_meta_destroy(meta);
1452 }
1453 }
1454 else {
1455 kate_meta_destroy(meta);
1456 }
1457 }
1458 if (ret<0) yyerrorf("failed to add metadata: %d",ret);
1459
1460 kate_free(byte_stream);
1461 byte_stream=NULL;
1462 n_bytes_in_stream=0;
1463 byte_stream_size=0;
1464 }
1465
check_event(kd_event * ev)1466 static kd_event *check_event(kd_event *ev)
1467 {
1468 /* we can set:
1469 start and end
1470 start and duration
1471 duration and end
1472 */
1473 int sets=0;
1474 if (ev->t0>=(kate_float)0.0) ++sets;
1475 if (ev->t1>=(kate_float)0.0) ++sets;
1476 if (ev->duration>=(kate_float)0.0) ++sets;
1477 if (sets<2) { yyerror("start/end times underspecified"); return NULL; }
1478 if (sets>2) { yyerror("start/end times overspecified"); return NULL; }
1479
1480 if (ev->t0<(kate_float)0.0) ev->t0=ev->t1-ev->duration;
1481 if (ev->t1<(kate_float)0.0) ev->t1=ev->t0+ev->duration;
1482
1483 return ev;
1484 }
1485
init_motion(void)1486 static void init_motion(void)
1487 {
1488 kmotions=(kd_motion*)kate_realloc(kmotions,(nkmotions+1)*sizeof(kd_motion));
1489 if (!kmotions) { yyerror("out of memory"); exit(-1); }
1490 ++nkmotions;
1491 kmotions[nkmotions-1].idx=0;
1492 kmotions[nkmotions-1].motion=kate_malloc(sizeof(kate_motion));
1493 kmotion=kmotions[nkmotions-1].motion;
1494 if (!kmotion) { yyerror("out of memory"); exit(-1); }
1495
1496 if (kate_motion_init(kmotion)<0) {
1497 yyerror("failed to init motion");
1498 exit(-1);
1499 }
1500 kmotion->semantics=(kate_motion_semantics)-1;
1501 }
1502
add_curve_to_motion(kate_motion * kmotion,kate_float duration)1503 static void add_curve_to_motion(kate_motion *kmotion,kate_float duration)
1504 {
1505 kmotion->ncurves++;
1506 kmotion->curves=(kate_curve**)kate_realloc(kmotion->curves,kmotion->ncurves*sizeof(kate_curve*));
1507 if (!kmotion->curves) { yyerror("out of memory"); exit(-1); }
1508 kmotion->durations=(kate_float*)kate_realloc(kmotion->durations,kmotion->ncurves*sizeof(kate_float));
1509 if (!kmotion->durations) { yyerror("out of memory"); exit(-1); }
1510
1511 if (kcurve.curve) {
1512 check_curve(kcurve.curve);
1513 kmotion->curves[kmotion->ncurves-1]=kcurve.curve;
1514 kcurve.curve=NULL;
1515 }
1516 else {
1517 if (kcurve.idx>=ki.ncurves) {
1518 yyerror("Internal error: curve index out of range");
1519 exit(-1);
1520 }
1521 kmotion->curves[kmotion->ncurves-1]=ki.curves[kcurve.idx];
1522 }
1523
1524 kmotion->durations[kmotion->ncurves-1]=duration;
1525 }
1526
get_num_glyphs(const char * text)1527 static size_t get_num_glyphs(const char *text)
1528 {
1529 size_t len0;
1530 size_t nglyphs=0;
1531 int intag=0,c;
1532
1533 if (!text) { yyerror("Internal error: get_num_glyphs got NULL text"); exit(-1); }
1534
1535 len0=strlen(text)+1;
1536 while ((c=kate_text_get_character(kate_utf8,&text,&len0))>0) {
1537 if (c=='<') intag++;
1538 if (!intag) ++nglyphs;
1539 if (c=='>') intag--;
1540 }
1541 return nglyphs;
1542 }
1543
init_simple_glyph_pointer_motion(void)1544 static void init_simple_glyph_pointer_motion(void)
1545 {
1546 init_motion();
1547 kmotion->semantics=kate_motion_semantics_glyph_pointer_1;
1548 karaoke_base_height=(kate_float)0;
1549 karaoke_top_height=(kate_float)0;
1550 }
1551
get_glyph_pointer_offset(unsigned int pointer_id)1552 static int get_glyph_pointer_offset(unsigned int pointer_id)
1553 {
1554 if (pointer_id<1 || pointer_id>4) {
1555 yyerrorf("Only glyph pointers 1-4 are available (trying to set %d)",pointer_id);
1556 exit(-1);
1557 }
1558 return (kate_motion_semantics)(kate_motion_semantics_glyph_pointer_1+pointer_id-1);
1559 }
1560
get_last_glyph_x(const kate_motion * km)1561 static kate_float get_last_glyph_x(const kate_motion *km)
1562 {
1563 const kate_curve *kc;
1564 if (!km) { yyerror("internal error: no motion"); exit(-1); }
1565 if (km->ncurves==0) return (kate_float)-0.5; /* by default, center of the glyph before the first one (eg, marks nothing yet) */
1566 kc=km->curves[km->ncurves-1];
1567 if (kc->npts<1) yyerror("internal error: no points in last curve");
1568 return kc->pts[kc->npts*2-2]; /* -1 would be y */
1569 }
1570
compute_karaoke_height(float y)1571 static kate_float compute_karaoke_height(float y)
1572 {
1573 /* turn height (bottom to top) to screen coordinates (top to bottom): negate */
1574 return -(karaoke_base_height*(1-y)+karaoke_top_height*y);
1575 }
1576
add_glyph_pause(kate_float dt,kate_float y)1577 static void add_glyph_pause(kate_float dt,kate_float y)
1578 {
1579 init_curve();
1580 kcurve.curve->type=kate_curve_static;
1581 kcurve.curve->npts=1;
1582 kcurve.curve->pts=(kate_float*)kate_malloc(kcurve.curve->npts*2*sizeof(kate_float));
1583 if (!kcurve.curve->pts) { yyerror("out of memory"); exit(-1); }
1584 kcurve.curve->pts[0]=get_last_glyph_x(kmotion);
1585 kcurve.curve->pts[1]=compute_karaoke_height(y);
1586 add_curve_to_motion(kmotion,dt);
1587 }
1588
add_glyph_transition(unsigned int glyph,kate_float dt,kate_float ystart,kate_float ytop,int absolute,kate_float pause_fraction)1589 static void add_glyph_transition(unsigned int glyph,kate_float dt,kate_float ystart,kate_float ytop,int absolute,kate_float pause_fraction)
1590 {
1591 /* get the last glyph position and the new one */
1592 kate_float x0=get_last_glyph_x(kmotion);
1593 kate_float x1=glyph+(kate_float)0.5;
1594 size_t n;
1595
1596 /* convert absolute to relative */
1597 if (absolute) {
1598 for (n=0;n<kmotion->ncurves;++n) dt-=kmotion->durations[n];
1599 }
1600
1601 if (dt<(kate_float)0.0) {
1602 yyerrorf("duration (%f) must not be negative\n",dt);
1603 exit(-1);
1604 }
1605
1606 /* add a pause before the next jump */
1607 if (pause_fraction>(kate_float)0.0) {
1608 kate_float delay=dt*pause_fraction;
1609 add_glyph_pause(delay,ystart);
1610 dt-=delay;
1611 if (dt<(kate_float)0.0) dt=(kate_float)0.0;
1612 x0=get_last_glyph_x(kmotion);
1613 }
1614
1615 init_curve();
1616
1617 if (dt==(kate_float)0.0) {
1618 /* if zero duration, just add static point at the end point */
1619 kcurve.curve->type=kate_curve_static;
1620 kcurve.curve->npts=1;
1621 kcurve.curve->pts=(kate_float*)kate_malloc(kcurve.curve->npts*2*sizeof(kate_float));
1622 if (!kcurve.curve->pts) { yyerror("out of memory"); exit(-1); }
1623 /* directly at the end position */
1624 kcurve.curve->pts[0]=x1;
1625 kcurve.curve->pts[1]=compute_karaoke_height(ystart);
1626 }
1627 else {
1628 kcurve.curve->type=kate_curve_catmull_rom_spline;
1629 kcurve.curve->npts=3+2; /* the two end points are duplicated */
1630 kcurve.curve->pts=(kate_float*)kate_malloc(kcurve.curve->npts*2*sizeof(kate_float));
1631 if (!kcurve.curve->pts) { yyerror("out of memory"); exit(-1); }
1632
1633 /* start position */
1634 kcurve.curve->pts[0]=kcurve.curve->pts[2]=x0;
1635 kcurve.curve->pts[1]=kcurve.curve->pts[3]=compute_karaoke_height(ystart);
1636
1637 /* the interpolated points */
1638 for (n=2;n<kcurve.curve->npts-2;++n) {
1639 kate_float t=(n-1)/(kate_float)(kcurve.curve->npts-2-1);
1640 kcurve.curve->pts[n*2]=kcurve.curve->pts[n*2+2]=x1*t+x0*((kate_float)1.0-t);
1641 kcurve.curve->pts[n*2+1]=kcurve.curve->pts[n*2+3]=compute_karaoke_height(ytop);
1642 }
1643
1644 /* end position */
1645 kcurve.curve->pts[kcurve.curve->npts*2-4]=kcurve.curve->pts[kcurve.curve->npts*2-2]=x1;
1646 kcurve.curve->pts[kcurve.curve->npts*2-3]=kcurve.curve->pts[kcurve.curve->npts*2-1]=compute_karaoke_height(ystart);
1647 }
1648
1649 add_curve_to_motion(kmotion,dt);
1650 }
1651
add_glyph_transition_to_text(const char * text,kate_float dt,kate_float ystart,kate_float ytop,int absolute,kate_float pause_fraction)1652 static void add_glyph_transition_to_text(const char *text,kate_float dt,kate_float ystart,kate_float ytop,int absolute,kate_float pause_fraction)
1653 {
1654 char *newtext;
1655
1656 if (!text) {
1657 yyerror("null text");
1658 return;
1659 }
1660
1661 if (kevent.text) {
1662 char *text2=(char*)kate_realloc(kevent.text,strlen(kevent.text)+strlen(text)+1);
1663 if (!text2) {
1664 yyerror("out of memory");
1665 return;
1666 }
1667 strcat(text2,text);
1668 kevent.text=text2;
1669 }
1670 else {
1671 char *text2=(char*)kate_malloc(strlen(text)+1);
1672 if (!text2) {
1673 yyerror("out of memory");
1674 return;
1675 }
1676 strcpy(text2,text);
1677 kevent.text=text2;
1678 }
1679
1680 backslash_n_to_newline(kevent.text);
1681 newtext=expand_numeric_entities(kevent.text);
1682 if (!newtext) return;
1683 kate_free(kevent.text);
1684 kevent.text=newtext;
1685
1686 add_glyph_transition(get_num_glyphs(kevent.text)-1,dt,ystart,ytop,absolute,pause_fraction);
1687 }
1688
set_style_morph(kd_event * ev,int from,int to)1689 static void set_style_morph(kd_event *ev,int from,int to)
1690 {
1691 int ret;
1692
1693 if (!ev) {
1694 yyerror("internal error: no event");
1695 exit(-1);
1696 }
1697 if (from<0 || to<0) {
1698 yyerror("error: style index cannot be negative");
1699 exit(-1);
1700 }
1701
1702 if (ev->style_index>=0 || ev->style) { yyerror("style already set"); return; }
1703 ev->style_index=from;
1704 ret=kate_encode_set_style_index(&k,from);
1705 if (ret<0) yyerrorf("failed to set style index: %d",ret);
1706
1707 if (ev->secondary_style_index>=0 || ev->secondary_style) { yyerror("secondary style already set"); return; }
1708 ev->secondary_style_index=to;
1709 ret=kate_encode_set_secondary_style_index(&k,to);
1710 if (ret<0) yyerrorf("failed to set secondary_style index: %d",ret);
1711 }
1712
clear_local_bitmaps(void)1713 static void clear_local_bitmaps(void)
1714 {
1715 size_t n;
1716
1717 if (local_bitmap_names) {
1718 for (n=0;n<n_local_bitmaps;++n) {
1719 if (local_bitmap_names[n]) kate_free(local_bitmap_names[n]);
1720 if (local_bitmaps[n]) {
1721 if(local_bitmaps[n]->meta) kate_meta_destroy(local_bitmaps[n]->meta);
1722 kate_free(local_bitmaps[n]->pixels);
1723 kate_free(local_bitmaps[n]);
1724 }
1725 }
1726 kate_free(local_bitmap_names);
1727 local_bitmap_names=NULL;
1728 kate_free(local_bitmaps);
1729 local_bitmaps=NULL;
1730 }
1731 n_local_bitmaps=0;
1732 }
1733
clear_event(kd_event * ev)1734 static void clear_event(kd_event *ev)
1735 {
1736 if (!ev) {
1737 yyerror("internal error: no event");
1738 exit(-1);
1739 }
1740 if (ev->text) {
1741 kate_free(ev->text);
1742 ev->text=NULL;
1743 }
1744 clear_motions();
1745 clear_local_bitmaps();
1746 }
1747
kd_finalize_simple_timed_glyph_motion(kate_motion * kmotion)1748 static void kd_finalize_simple_timed_glyph_motion(kate_motion *kmotion)
1749 {
1750 const kd_event *ev=&kevent;
1751 kate_float duration=ev->duration;
1752 kate_float t0=ev->t0,t1=ev->t1;
1753 kate_float duration_so_far;
1754 size_t n;
1755 int sets;
1756
1757 if (!kmotion) {
1758 yyerror("internal error: kd_finalize_simple_timed_glyph_motion passed NULL motion");
1759 exit(-1);
1760 }
1761
1762 /* for this helper motion, we require the timing of the event to be known in advance */
1763 sets=0;
1764 if (t0>=(kate_float)0.0) ++sets;
1765 if (t1>=(kate_float)0.0) ++sets;
1766 if (duration>=(kate_float)0.0) ++sets;
1767 if (sets<2) { yyerror("start/end times must be specified before timed glyph marker motion setup"); return; }
1768 if (sets>2) { yyerror("start/end times overspecified"); return; }
1769
1770 if (t0<(kate_float)0.0) t0=t1-duration;
1771 if (t1<(kate_float)0.0) t1=t0+duration;
1772 duration=t1-t0;
1773
1774 /* add a pause to take us to the end time */
1775 duration_so_far=(kate_float)0.0;
1776 for (n=0;n<kmotion->ncurves;++n) duration_so_far+=kmotion->durations[n];
1777 if (duration_so_far>duration) {
1778 yyerrorf("Simple timed glyph motion lasts longer than its event (motion %f, event %f)",duration_so_far,duration);
1779 exit(-1);
1780 }
1781 add_glyph_pause(duration-duration_so_far,(kate_float)1.0);
1782 }
1783
set_motion_mapping(kate_motion * kmotion,kate_motion_mapping x_mapping,kate_motion_mapping y_mapping)1784 static void set_motion_mapping(kate_motion *kmotion,kate_motion_mapping x_mapping,kate_motion_mapping y_mapping)
1785 {
1786 if (!kmotion) {
1787 yyerror("internal error: set_motion_mapping passed NULL motion");
1788 exit(-1);
1789 }
1790
1791 kmotion->x_mapping=x_mapping;
1792 kmotion->y_mapping=y_mapping;
1793 }
1794
set_motion_semantics(kate_motion * kmotion,kate_motion_semantics semantics)1795 static void set_motion_semantics(kate_motion *kmotion,kate_motion_semantics semantics)
1796 {
1797 if (!kmotion) {
1798 yyerror("internal error: set_motion_semantics passed NULL motion");
1799 exit(-1);
1800 }
1801
1802 if (kmotion->semantics!=(kate_motion_semantics)-1) { yyerror("semantics is already defined"); return; }
1803 kmotion->semantics=semantics;
1804 }
1805
kd_get_marker_position_semantics(int n)1806 static kate_motion_semantics kd_get_marker_position_semantics(int n)
1807 {
1808 switch (n) {
1809 case 1: return kate_motion_semantics_marker1_position;
1810 case 2: return kate_motion_semantics_marker2_position;
1811 case 3: return kate_motion_semantics_marker3_position;
1812 case 4: return kate_motion_semantics_marker4_position;
1813 default: yyerrorf("Invalid marker number: %d (only 1-4 are supported)",n); exit(-1);
1814 }
1815 return kate_motion_semantics_marker4_position;
1816 }
1817
kd_get_marker_bitmap_semantics(int n)1818 static kate_motion_semantics kd_get_marker_bitmap_semantics(int n)
1819 {
1820 switch (n) {
1821 case 1: return kate_motion_semantics_marker1_bitmap;
1822 case 2: return kate_motion_semantics_marker2_bitmap;
1823 case 3: return kate_motion_semantics_marker3_bitmap;
1824 case 4: return kate_motion_semantics_marker4_bitmap;
1825 default: yyerrorf("Invalid marker number: %d (only 1-4 are supported)",n); exit(-1);
1826 }
1827 return kate_motion_semantics_marker4_bitmap;
1828 }
1829
kd_get_glyph_pointer_semantics(int n)1830 static kate_motion_semantics kd_get_glyph_pointer_semantics(int n)
1831 {
1832 switch (n) {
1833 case 1: return kate_motion_semantics_glyph_pointer_1;
1834 case 2: return kate_motion_semantics_glyph_pointer_2;
1835 case 3: return kate_motion_semantics_glyph_pointer_3;
1836 case 4: return kate_motion_semantics_glyph_pointer_4;
1837 default: yyerrorf("Invalid glyph pointer number: %d (only 1-4 are supported)",n); exit(-1);
1838 }
1839 return kate_motion_semantics_glyph_pointer_4;
1840 }
1841
kd_get_glyph_pointer_bitmap_semantics(int n)1842 static kate_motion_semantics kd_get_glyph_pointer_bitmap_semantics(int n)
1843 {
1844 switch (n) {
1845 case 1: return kate_motion_semantics_glyph_pointer_1_bitmap;
1846 case 2: return kate_motion_semantics_glyph_pointer_2_bitmap;
1847 case 3: return kate_motion_semantics_glyph_pointer_3_bitmap;
1848 case 4: return kate_motion_semantics_glyph_pointer_4_bitmap;
1849 default: yyerrorf("Invalid glyph pointer number: %d (only 1-4 are supported)",n); exit(-1);
1850 }
1851 return kate_motion_semantics_glyph_pointer_4_bitmap;
1852 }
1853
kd_add_event_motion(kate_motion * kmotion)1854 static void kd_add_event_motion(kate_motion *kmotion)
1855 {
1856 int ret;
1857
1858 if (!kmotion) {
1859 yyerror("internal error: kd_add_event_motion passed NULL motion");
1860 exit(-1);
1861 }
1862
1863 check_motion(kmotion);
1864 ret=kate_encode_add_motion(&k,kmotion,1);
1865 if (ret<0) {
1866 yyerrorf("failed to add motion: %d",ret);
1867 exit(-1);
1868 }
1869 clear_motions();
1870 }
1871
kd_add_event_motion_index(size_t idx)1872 static void kd_add_event_motion_index(size_t idx)
1873 {
1874 int ret;
1875
1876 if (idx>=ki.nmotions) { yyerrorf("Motion index %u out of range (%u motions available)",idx,ki.nmotions); exit(-1); }
1877
1878 ret=kate_encode_add_motion_index(&k,idx);
1879 if (ret<0) {
1880 yyerrorf("failed to add motion: %d",ret);
1881 exit(-1);
1882 }
1883 clear_motions();
1884 }
1885
init_font_range(void)1886 static void init_font_range(void)
1887 {
1888 krange=(kate_font_range*)kate_malloc(sizeof(kate_font_range));
1889 if (!krange) { yyerror("out of memory"); exit(-1); }
1890 krange->first_code_point=-1;
1891 krange->last_code_point=-1;
1892 krange->first_bitmap=-1;
1893 }
1894
set_font_range_code_point_string(int * cp,const char * s)1895 static void set_font_range_code_point_string(int *cp,const char *s)
1896 {
1897 size_t len0;
1898 int ret,c;
1899
1900 if (!cp) { yyerror("internal error: no code point pointer"); exit(-1); }
1901 if (!s) { yyerror("internal error: no string"); exit(-1); }
1902 len0=strlen(s)+1;
1903 ret=kate_text_get_character(kate_utf8,&s,&len0);
1904 if (ret<0) {
1905 yyerrorf("failed to get character from string: %d",ret);
1906 return;
1907 }
1908 c=ret;
1909 ret=kate_text_get_character(kate_utf8,&s,&len0);
1910 if (ret<0) {
1911 yyerrorf("failed to get character from string: %d",ret);
1912 return;
1913 }
1914 if (ret) {
1915 yyerror("code point string should contain only one character");
1916 return;
1917 }
1918 *cp=c;
1919 }
1920
set_font_range_first_code_point_string(const char * s)1921 static void set_font_range_first_code_point_string(const char *s)
1922 {
1923 if (!s) { yyerror("internal error: no string"); exit(-1); }
1924 if (!krange) { yyerror("internal error: no font range"); exit(-1); }
1925 set_font_range_code_point_string(&krange->first_code_point,s);
1926 }
1927
set_font_range_last_code_point_string(const char * s)1928 static void set_font_range_last_code_point_string(const char *s)
1929 {
1930 if (!s) { yyerror("internal error: no string"); exit(-1); }
1931 if (!krange) { yyerror("internal error: no font range"); exit(-1); }
1932 set_font_range_code_point_string(&krange->last_code_point,s);
1933 }
1934
set_font_range_first_code_point(int idx)1935 static void set_font_range_first_code_point(int idx)
1936 {
1937 if (!krange) { yyerror("internal error: no font range"); exit(-1); }
1938 krange->first_code_point=idx;
1939 }
1940
set_font_range_last_code_point(int idx)1941 static void set_font_range_last_code_point(int idx)
1942 {
1943 if (!krange) { yyerror("internal error: no font range"); exit(-1); }
1944 krange->last_code_point=idx;
1945 }
1946
set_font_range_first_bitmap(int idx)1947 static void set_font_range_first_bitmap(int idx)
1948 {
1949 if (!krange) { yyerror("internal error: no font range"); exit(-1); }
1950 krange->first_bitmap=idx;
1951 }
1952
add_font_range(kate_info * ki,const char * name,kate_font_range * kfr)1953 static void add_font_range(kate_info *ki,const char *name,kate_font_range *kfr)
1954 {
1955 int ret;
1956 if (!ki || !kfr) { yyerror("internal error: no kate_info or kate_font_range"); exit(-1); }
1957 if (!krange) { yyerror("internal error: no font range"); exit(-1); }
1958 if (krange->first_code_point<0) yyerror("first code point not set");
1959 if (krange->last_code_point<0) yyerror("last code point not set");
1960 if (krange->last_code_point<krange->first_code_point) yyerror("last code point cannnot be less than first code point");
1961 if (krange->first_bitmap<0) yyerror("bitmap index not set");
1962 ret=kate_info_add_font_range(ki,kfr);
1963 if (ret<0) {
1964 yyerrorf("failed to add font range: %d",ret);
1965 }
1966 else {
1967 font_range_names=(char**)kate_realloc(font_range_names,ki->nfont_ranges*sizeof(char*));
1968 if (!font_range_names) {
1969 yyerror("Out of memory");
1970 exit(-1);
1971 }
1972 font_range_names[ki->nfont_ranges-1]=name?dupstring(name):NULL;
1973 }
1974 }
1975
find_font_range(const kate_info * ki,const char * name)1976 static int find_font_range(const kate_info *ki,const char *name)
1977 {
1978 return find_item(name,ki->nfont_ranges,font_range_names);
1979 }
1980
init_font_mapping(void)1981 static void init_font_mapping(void)
1982 {
1983 kmapping=(kate_font_mapping*)kate_malloc(sizeof(kate_font_mapping));
1984 if (!kmapping) { yyerror("out of memory"); exit(-1); }
1985 kmapping->nranges=0;
1986 kmapping->ranges=NULL;
1987 }
1988
check_font_overlap(const kate_font_range * kfr0,const kate_font_range * kfr1)1989 static int check_font_overlap(const kate_font_range *kfr0,const kate_font_range *kfr1)
1990 {
1991 if (!kfr0 || !kfr1) return KATE_E_INVALID_PARAMETER;
1992
1993 if (kfr0->last_code_point<kfr1->first_code_point) return 0;
1994 if (kfr1->last_code_point<kfr0->first_code_point) return 0;
1995
1996 return KATE_E_INIT;
1997 }
1998
check_font_ranges(const kate_font_mapping * kfm)1999 static int check_font_ranges(const kate_font_mapping *kfm)
2000 {
2001 size_t n,l;
2002
2003 if (!kfm) return KATE_E_INVALID_PARAMETER;
2004
2005 for (n=0;n<kfm->nranges;++n) {
2006 const kate_font_range *kfr=kfm->ranges[n];
2007 if (!kfr) return KATE_E_INIT;
2008 if (kfr->last_code_point<kfr->first_code_point) return KATE_E_INIT;
2009 for (l=n+1;l<kfm->nranges;++l) {
2010 int ret=check_font_overlap(kfr,kfm->ranges[l]);
2011 if (ret<0) return ret;
2012 }
2013 }
2014
2015 return 0;
2016 }
2017
add_font_range_to_mapping(void)2018 static void add_font_range_to_mapping(void)
2019 {
2020 int ret;
2021
2022 if (!krange) { yyerror("internal error: no font range"); exit(-1); }
2023 if (!kmapping) { yyerror("internal error: no font mapping"); exit(-1); }
2024
2025 kmapping->ranges=(kate_font_range**)kate_realloc(kmapping->ranges,(kmapping->nranges+1)*sizeof(kate_font_range*));
2026 if (!kmapping->ranges) {
2027 yyerror("error: out of memory");
2028 exit(-1);
2029 }
2030 kmapping->ranges[kmapping->nranges]=krange;
2031 ++kmapping->nranges;
2032
2033 ret=check_font_ranges(kmapping);
2034 if (ret<0) yyerror("font mapping ranges overlap");
2035
2036 krange=NULL;
2037 }
2038
add_font_mapping(kate_info * ki,const char * name,kate_font_mapping * kfm)2039 static void add_font_mapping(kate_info *ki,const char *name,kate_font_mapping *kfm)
2040 {
2041 int ret;
2042 if (!ki) { yyerror("internal error: no kate_info"); exit(-1); }
2043 if (!kfm) { yyerror("internal error: no font mapping"); exit(-1); }
2044 if (kfm->nranges==0) yyerror("font mapping has no ranges");
2045 ret=kate_info_add_font_mapping(ki,kfm);
2046 if (ret<0) {
2047 yyerrorf("failed to add font mapping: %d",ret);
2048 }
2049 else {
2050 font_mapping_names=(char**)kate_realloc(font_mapping_names,ki->nfont_mappings*sizeof(char*));
2051 if (!font_mapping_names) {
2052 yyerror("Out of memory");
2053 exit(-1);
2054 }
2055 font_mapping_names[ki->nfont_mappings-1]=name?dupstring(name):NULL;
2056 }
2057 }
2058
find_font_mapping(const kate_info * ki,const char * name)2059 static int find_font_mapping(const kate_info *ki,const char *name)
2060 {
2061 return find_item(name,ki->nfont_mappings,font_mapping_names);
2062 }
2063
kd_write_headers(void)2064 static void kd_write_headers(void)
2065 {
2066 int ret=write_headers(katedesc_out);
2067 if (ret<0) {
2068 yyerrorf("Failed to write headers: %d\n",ret);
2069 exit(-1);
2070 }
2071 }
2072
kd_encode_text(kate_state * kstate,kd_event * ev)2073 static void kd_encode_text(kate_state *kstate,kd_event *ev)
2074 {
2075 int ret;
2076 ogg_packet op;
2077
2078 if (!ev) { yyerror("internal error: no event"); exit(-1); }
2079 ret=kate_encode_set_markup_type(kstate,ev->text_markup_type);
2080 if (ret<0) {
2081 yyerrorf("failed to set text markup type: %d",ret);
2082 return;
2083 }
2084 update_stream_time(kstate,katedesc_out,kate_duration_granule(kstate->ki,timebase+ev->t0));
2085 ret=kate_ogg_encode_text(kstate,timebase+ev->t0,timebase+ev->t1,ev->text?ev->text:"",ev->text?strlen(ev->text):0,&op);
2086 if (ret<0) {
2087 yyerrorf("failed to encode text %s: %d",ev->text?ev->text:"<none>",ret);
2088 return;
2089 }
2090 ret=send_packet(katedesc_out,&op,kate_duration_granule(kstate->ki,timebase+ev->t0));
2091 if (ret<0) {
2092 yyerrorf("failed to send text packet: %d",ret);
2093 }
2094 }
2095
kd_encode_set_language(kate_state * kstate,const char * s)2096 static void kd_encode_set_language(kate_state *kstate,const char *s)
2097 {
2098 int ret;
2099 if (!s) { yyerror("internal error: no language string"); exit(-1); }
2100 ret=kate_encode_set_language(kstate,s);
2101 if (ret<0) yyerrorf("failed to set event language override: %d",ret);
2102 }
2103
make_color(uint32_t r,uint32_t g,uint32_t b,uint32_t a)2104 static uint32_t make_color(uint32_t r,uint32_t g,uint32_t b,uint32_t a)
2105 {
2106 return (r<<24)|(g<<16)|(b<<8)|a;
2107 }
2108
make_color_alpha(uint32_t c,uint32_t a)2109 static uint32_t make_color_alpha(uint32_t c,uint32_t a)
2110 {
2111 return (c&0xffffff00)|a;
2112 }
2113
record_macro_name(const char * name)2114 static void record_macro_name(const char *name)
2115 {
2116 size_t len;
2117 if (!name) { yyerror("internal error: no macro name"); exit(-1); }
2118 len=strlen(name);
2119 if (temp_macro_name) kate_free(temp_macro_name);
2120 temp_macro_name=kate_malloc(len+1);
2121 if (!temp_macro_name) { yyerror("out of memory"); exit(-1); }
2122 strcpy(temp_macro_name,name);
2123 }
2124
add_temp_macro(const char * body)2125 static void add_temp_macro(const char *body)
2126 {
2127 if (!body) { yyerror("internal error: no macro body"); exit(-1); }
2128 if (!temp_macro_name) { yyerror("internal error - unknown macro name"); return; }
2129 add_macro(temp_macro_name,body);
2130 kate_free(temp_macro_name);
2131 temp_macro_name=NULL;
2132 }
2133
set_granule_rate(unsigned int numerator,unsigned int denominator)2134 static void set_granule_rate(unsigned int numerator,unsigned int denominator)
2135 {
2136 ki.gps_numerator=numerator;
2137 ki.gps_denominator=denominator;
2138 }
2139
set_granule_shift(unsigned int granule_shift)2140 static void set_granule_shift(unsigned int granule_shift)
2141 {
2142 if (granule_shift>=64) yyerror("granule shift out of range (0-64)\n");
2143 ki.granule_shift=granule_shift;
2144 }
2145
set_canvas_size(unsigned int width,unsigned int height)2146 static void set_canvas_size(unsigned int width,unsigned int height)
2147 {
2148 int ret=kate_info_set_original_canvas_size(&ki,width,height);
2149 if (ret<0) {
2150 yyerror("failed to set original canvas size");
2151 exit(-1);
2152 }
2153 }
2154
add_comment(kate_comment * kc,const char * s)2155 static void add_comment(kate_comment *kc,const char *s)
2156 {
2157 /* check for "ENCODER=," as kateenc now sets it and we don't want cycles
2158 of decode/encode to duplicate them, and we want the new one to replace
2159 any existing one */
2160 int different=0;
2161 const char *encoder="ENCODER=",*sptr=s;
2162 while (*encoder) if ((*encoder++|32)!=(*sptr++|32)) {
2163 different=1;
2164 break;
2165 }
2166 if (different) {
2167 CHECK_KATE_API_ERROR(kate_comment_add(kc,s));
2168 }
2169 }
2170
cleanup_names(char ** names,size_t count)2171 static void cleanup_names(char **names,size_t count)
2172 {
2173 size_t n;
2174 if (names) {
2175 for (n=0;n<count;++n) if (names[n]) kate_free(names[n]);
2176 kate_free(names);
2177 }
2178 }
2179
cleanup_memory(void)2180 static void cleanup_memory(void)
2181 {
2182 cleanup_names(style_names,ki.nstyles);
2183 cleanup_names(region_names,ki.nregions);
2184 cleanup_names(curve_names,ki.ncurves);
2185 cleanup_names(motion_names,ki.nmotions);
2186 cleanup_names(bitmap_names,ki.nbitmaps);
2187 cleanup_names(palette_names,ki.npalettes);
2188 cleanup_names(font_range_names,ki.nfont_ranges);
2189 cleanup_names(font_mapping_names,ki.nfont_mappings);
2190 cleanup_names(local_bitmap_names,n_local_bitmaps);
2191
2192 free_macros();
2193 }
2194
2195
2196 %}
2197
2198 %pure_parser
2199
2200 %union {
2201 int number;
2202 unsigned int unumber;
2203 kate_float fp;
2204 const char *string;
2205 char *dynstring;
2206 kate_style *style;
2207 kate_region *region;
2208 kate_curve *curve;
2209 uint32_t color;
2210 }
2211
2212 %token <number> KATE
2213 %token <number> DEFS
2214 %token <number> LANGUAGE COMMENT CATEGORY
2215 %token <number> DEFINE MACRO STYLE REGION CURVE
2216 %token <number> TEXT BACKGROUND COLOR POSITION SIZE DEFAULT METRIC
2217 %token <number> HALIGN VALIGN HLEFT HCENTER HRIGHT VTOP VCENTER VBOTTOM
2218 %token <number> POINTS
2219 %token <number> EVENT STARTS ENDS AT START END TIME DURATION ARROW FROM TO
2220 %token <number> MAPPING NONE FRAME MOTION BEZIER_CUBIC LINEAR CATMULL_ROM
2221 %token <number> BSPLINE STATIC
2222 %token <number> SEMANTICS EXTERNAL INTERNAL ALIGNMENT RG BA FOR ALPHA
2223 %token <number> TIMEBASE MARKER POINTER
2224 %token <number> SIMPLE_TIMED_GLYPH_MARKER
2225 %token <number> SIMPLE_TIMED_GLYPH_STYLE_MORPH
2226 %token <number> GLYPH PAUSE IN MORPH SECONDARY
2227 %token <number> PATH SECTION PERIODIC
2228 %token <number> DIRECTIONALITY L2R_T2B R2L_T2B T2B_R2L T2B_L2R
2229 %token <number> BITMAP PALETTE COLORS
2230 %token <number> FONT RANGE FIRST LAST CODE POINT
2231 %token <number> USER SOURCE PNG DRAW VISIBLE
2232 %token <number> ID BOLD ITALICS UNDERLINE STRIKE JUSTIFY
2233 %token <number> BASE OFFSET GRANULE RATE SHIFT WIDTH HEIGHT CANVAS
2234 %token <number> LEFT TOP RIGHT BOTTOM MARGIN MARGINS
2235 %token <number> HORIZONTAL VERTICAL CLIP PRE MARKUP
2236 %token <number> LOCAL WRAP WORD META
2237
2238 %token <number> NUMBER
2239 %token <unumber> UNUMBER
2240 %token <string> STRING
2241 %token <fp> FLOAT
2242 %token <color> COLORSPEC
2243 %token <string> IDENTIFIER MACRO_BODY
2244
2245 %type <number> kd_kate kd_opt_defs kd_defs kd_def kd_events kd_event
2246 %type <number> kd_curve_points kd_palette_colors
2247 %type <number> kd_bitmap_pixels kd_png_bitmap_pixels
2248 %type <number> kd_style_defs kd_style_def
2249 %type <number> kd_region_defs kd_region_def
2250 %type <number> kd_curve_defs kd_curve_def
2251 %type <number> kd_palette_defs kd_palette_def
2252 %type <number> kd_bitmap_defs kd_bitmap_def
2253 %type <number> kd_font_range_defs kd_font_range_def
2254 %type <number> kd_font_mapping_defs kd_font_mapping_def
2255 %type <string> kd_opt_name
2256 %type <number> kd_style_name_or_index
2257 %type <number> kd_region_name_or_index
2258 %type <number> kd_curve_name_or_index kd_curve_def_name_or_index
2259 %type <number> kd_palette_name_or_index
2260 %type <number> kd_bitmap_name_or_index
2261 %type <number> kd_motion_name_or_index
2262 %type <number> kd_font_range_name_or_index
2263 %type <number> kd_font_mapping_name_or_index
2264 %type <fp> kd_optional_curve_duration
2265 %type <fp> float timespec
2266 %type <number> kd_event_defs kd_event_def
2267 %type <number> kd_motion_defs kd_motion_def
2268 %type <number> kd_motion_mapping kd_motion_semantics
2269 %type <number> kd_curvetype
2270 %type <color> kd_color
2271 %type <number> kd_simple_timed_glyph_marker_defs kd_simple_timed_glyph_marker_def
2272 %type <number> kd_simple_timed_glyph_style_morph_defs kd_simple_timed_glyph_style_morph_def
2273 %type <number> kd_opt_comma
2274 %type <number> bitmap_x_offset bitmap_y_offset
2275 %type <fp> float60
2276 %type <unumber> unumber60
2277 %type <dynstring> strings
2278 %type <number> kd_optional_secondary
2279 %type <number> directionality
2280 %type <number> kd_opt_space_metric
2281 %type <number> kd_wrap_mode
2282 %type <number> kd_meta_byte_stream_def kd_byte_stream
2283
2284 %%
2285
2286 kd_kate: {nlines=1;} KATE '{' kd_opt_defs { kd_write_headers(); } kd_events '}' { cleanup_memory(); }
2287 ;
2288
2289 kd_opt_defs: DEFS '{' kd_defs '}'
2290 | {}
2291 ;
2292
2293 kd_defs: kd_defs kd_def
2294 | {}
2295 ;
2296
2297 kd_def: LANGUAGE STRING { CHECK_KATE_API_ERROR(kate_info_set_language(&ki,$2)); }
2298 | CATEGORY STRING { CHECK_KATE_API_ERROR(kate_info_set_category(&ki,$2)); }
2299 | DIRECTIONALITY directionality { CHECK_KATE_API_ERROR(kate_info_set_text_directionality(&ki,$2)); }
2300 | COMMENT STRING { add_comment(&kc,$2); }
2301 | DEFINE MACRO {set_macro_mode();} IDENTIFIER {record_macro_name($4);} MACRO_BODY
2302 { add_temp_macro($6); unset_macro_mode(); }
2303 | DEFINE STYLE kd_opt_name {init_style(&kstyle);} '{' kd_style_defs '}' { add_style(&ki,$3,&kstyle); }
2304 | DEFINE REGION kd_opt_name {init_region(&kregion);} '{' kd_region_defs '}' { add_region(&ki,$3,&kregion); }
2305 | DEFINE CURVE kd_opt_name {init_curve();} '{' kd_curve_defs '}' { add_curve(&ki,$3,kcurve.curve); }
2306 | DEFINE MOTION kd_opt_name {init_motion();} '{' kd_motion_defs '}' { add_motion(&ki,$3,kmotion); }
2307 | DEFINE PALETTE kd_opt_name {init_palette();} '{' kd_palette_defs '}' { add_palette(&ki,$3,kpalette.palette); }
2308 | DEFINE BITMAP kd_opt_name {init_bitmap();} '{' kd_bitmap_defs '}' { add_bitmap(&ki,$3,kbitmap.bitmap); }
2309 | DEFINE FONT RANGE kd_opt_name {init_font_range();} '{' kd_font_range_defs '}' { add_font_range(&ki,$4,krange); }
2310 | DEFINE FONT MAPPING kd_opt_name {init_font_mapping();} '{' kd_font_mapping_defs '}' { add_font_mapping(&ki,$4,kmapping); }
2311 | TIMEBASE timespec { timebase=$2; }
2312 | GRANULE RATE UNUMBER '/' UNUMBER {set_granule_rate($3,$5);}
2313 | GRANULE SHIFT UNUMBER {set_granule_shift($3);}
2314 | CANVAS SIZE UNUMBER UNUMBER {set_canvas_size($3,$4);}
2315 ;
2316
2317 kd_style_defs: kd_style_defs kd_style_def
2318 | {}
2319 ;
2320
2321 kd_style_def: HALIGN float { kstyle.halign=$2; }
2322 | VALIGN float { kstyle.valign=$2; }
2323 | HLEFT { kstyle.halign=(kate_float)-1.0; }
2324 | HCENTER { kstyle.halign=(kate_float)0.0; }
2325 | HRIGHT { kstyle.halign=(kate_float)1.0; }
2326 | VTOP { kstyle.valign=(kate_float)-1.0; }
2327 | VCENTER { kstyle.valign=(kate_float)0.0; }
2328 | VBOTTOM { kstyle.valign=(kate_float)1.0; }
2329 | TEXT COLOR kd_color { set_color(&kstyle.text_color,$3); }
2330 | BACKGROUND COLOR kd_color { set_color(&kstyle.background_color,$3); }
2331 | DRAW COLOR kd_color { set_color(&kstyle.draw_color,$3); }
2332 | BOLD { kstyle.bold=1; }
2333 | ITALICS { kstyle.italics=1; }
2334 | UNDERLINE { kstyle.underline=1; }
2335 | STRIKE { kstyle.strike=1; }
2336 | JUSTIFY { kstyle.justify=1; }
2337 | WRAP kd_wrap_mode { kstyle.wrap_mode=$2; }
2338 | FONT STRING { set_font(&kstyle,$2); }
2339 | FONT SIZE float kd_opt_space_metric { set_font_size(&kstyle,$3,$4); }
2340 | FONT WIDTH float kd_opt_space_metric { set_font_width(&kstyle,$3,$4); }
2341 | FONT HEIGHT float kd_opt_space_metric { set_font_height(&kstyle,$3,$4); }
2342 | LEFT MARGIN float kd_opt_space_metric { set_margin(&kstyle,&kstyle.left_margin,$3,$4); }
2343 | TOP MARGIN float kd_opt_space_metric { set_margin(&kstyle,&kstyle.top_margin,$3,$4); }
2344 | RIGHT MARGIN float kd_opt_space_metric { set_margin(&kstyle,&kstyle.right_margin,$3,$4); }
2345 | BOTTOM MARGIN float kd_opt_space_metric { set_margin(&kstyle,&kstyle.bottom_margin,$3,$4); }
2346 | MARGINS float kd_opt_space_metric float kd_opt_space_metric float kd_opt_space_metric float kd_opt_space_metric
2347 { set_margins(&kstyle,$2,$3,$4,$5,$6,$7,$8,$9); }
2348 | META STRING '=' STRING { add_meta(&kstyle.meta,$2,$4); }
2349 | META STRING '=' UNUMBER {init_byte_stream($4);} '{' kd_byte_stream '}' { add_meta_byte_stream(&kstyle.meta,$2); }
2350 ;
2351
2352 kd_opt_space_metric: '%' { $$=kate_percentage; }
2353 | 'm' { $$=kate_millionths; }
2354 | { $$=kate_pixel; }
2355 ;
2356
2357 kd_region_defs: kd_region_defs kd_region_def
2358 | {}
2359 ;
2360
2361 kd_region_def: METRIC {kregion.metric=$1; }
2362 | POSITION float float { kregion.x=$2;kregion.y=$3; }
2363 | SIZE float float { kregion.w=$2;kregion.h=$3; }
2364 | CLIP { kregion.clip=1; }
2365 | DEFAULT STYLE kd_style_name_or_index { kregion.style=$3; }
2366 | META STRING '=' STRING { add_meta(&kregion.meta,$2,$4); }
2367 | META STRING '=' UNUMBER {init_byte_stream($4);} '{' kd_byte_stream '}' { add_meta_byte_stream(&kregion.meta,$2); }
2368 ;
2369
2370 kd_curve_defs: kd_curve_defs kd_curve_def
2371 | {}
2372 ;
2373
2374 kd_curve_def: kd_curvetype { kcurve.curve->type=$1; n_curve_pts=0; }
2375 | UNUMBER POINTS { init_curve_points($1); } '{' kd_curve_points '}' {
2376 if ((size_t)n_curve_pts!=kcurve.curve->npts*2) katedesc_error("Wrong number of points in the curve");
2377 }
2378 | POINTS { init_open_ended_curve_points(); } '{' kd_curve_points '}'
2379 ;
2380
2381 kd_palette_defs: kd_palette_defs kd_palette_def
2382 | {}
2383 ;
2384
2385 kd_palette_def: UNUMBER COLORS { init_palette_colors($1); } '{' kd_palette_colors '}' {
2386 if ((size_t)n_palette_colors!=kpalette.palette->ncolors) {
2387 katedesc_error("Wrong number of colors in the palette");
2388 }
2389 }
2390 | SOURCE STRING { load_palette($2); }
2391 ;
2392
2393 kd_bitmap_defs: kd_bitmap_defs kd_bitmap_def
2394 | {}
2395 ;
2396
2397 kd_bitmap_def: UNUMBER 'x' UNUMBER 'x' UNUMBER { init_bitmap_pixels($1,$3,$5); } '{' kd_bitmap_pixels '}' {
2398 if ((size_t)n_bitmap_pixels!=kbitmap.bitmap->width*kbitmap.bitmap->height) {
2399 katedesc_error("Wrong number of pixels in the bitmap");
2400 }
2401 }
2402 | UNUMBER 'x' UNUMBER PNG UNUMBER { init_png_bitmap_pixels($1,$3,$5); } '{' kd_png_bitmap_pixels '}' {
2403 if ((size_t)n_bitmap_pixels!=kbitmap.bitmap->size) {
2404 katedesc_error("Wrong number of bytes in the PNG bitmap");
2405 }
2406 }
2407 | SOURCE STRING { load_bitmap($2,0); }
2408 | DEFAULT PALETTE kd_palette_name_or_index { kbitmap.bitmap->palette=$3; }
2409 | OFFSET bitmap_x_offset bitmap_y_offset { kbitmap.bitmap->x_offset=$2; kbitmap.bitmap->y_offset=$3; }
2410 | META STRING '=' STRING { add_meta(&kbitmap.bitmap->meta,$2,$4); }
2411 | META STRING '=' UNUMBER {init_byte_stream($4);} '{' kd_byte_stream '}' { add_meta_byte_stream(&kbitmap.bitmap->meta,$2); }
2412 ;
2413
2414 kd_color: UNUMBER UNUMBER UNUMBER { $$=make_color($1,$2,$3,255); }
2415 | UNUMBER UNUMBER UNUMBER UNUMBER { $$=make_color($1,$2,$3,$4); }
2416 | COLORSPEC { $$=make_color_alpha($1,255); }
2417 | COLORSPEC ALPHA UNUMBER { $$=make_color_alpha($1,$3); }
2418 ;
2419
2420 kd_wrap_mode: NONE { $$=kate_wrap_none; }
2421 | WORD { $$=kate_wrap_word; }
2422 ;
2423
2424 kd_curvetype: NONE { $$=kate_curve_none; }
2425 | STATIC { $$=kate_curve_static; }
2426 | LINEAR { $$=kate_curve_linear; }
2427 | CATMULL_ROM { $$=kate_curve_catmull_rom_spline; }
2428 | BEZIER_CUBIC { $$=kate_curve_bezier_cubic_spline; }
2429 | BSPLINE { $$=kate_curve_bspline; }
2430 ;
2431
2432 kd_curve_points: kd_curve_points float {
2433 if (open_ended_curve) {
2434 add_open_ended_curve_point($2);
2435 }
2436 else {
2437 if ((size_t)n_curve_pts>=kcurve.curve->npts*2) katedesc_error("Too many points in curve");
2438 else { kcurve.curve->pts[n_curve_pts++]=$2; }
2439 }
2440 }
2441 | {}
2442 ;
2443
2444 kd_palette_colors: kd_palette_colors '{' kd_color '}' kd_opt_comma {
2445 if ((size_t)n_palette_colors>=kpalette.palette->ncolors) katedesc_error("Too many colors in palette");
2446 else { set_color(&kpalette.palette->colors[n_palette_colors++],$3); }
2447 }
2448 | {}
2449 ;
2450
2451 kd_bitmap_pixels: kd_bitmap_pixels UNUMBER kd_opt_comma {
2452 if ((size_t)n_bitmap_pixels>=kbitmap.bitmap->width*kbitmap.bitmap->height) {
2453 katedesc_error("Too many pixels in bitmap");
2454 }
2455 else {
2456 if ($2>(unsigned int)(1<<kbitmap.bitmap->bpp)-1) {
2457 katedesc_error("pixels out of range for given bpp");
2458 }
2459 else {
2460 kbitmap.bitmap->pixels[n_bitmap_pixels++]=$2;
2461 }
2462 }
2463 }
2464 | {}
2465 ;
2466
2467 kd_png_bitmap_pixels: kd_png_bitmap_pixels UNUMBER kd_opt_comma {
2468 if ((size_t)n_bitmap_pixels>=kbitmap.bitmap->size) {
2469 katedesc_error("Too many pixels in bitmap");
2470 }
2471 else {
2472 kbitmap.bitmap->pixels[n_bitmap_pixels++]=$2;
2473 }
2474 }
2475 | {}
2476 ;
2477
2478 kd_byte_stream: kd_byte_stream UNUMBER kd_opt_comma {
2479 if (n_bytes_in_stream>=byte_stream_size) {
2480 katedesc_error("Too many bytes in byte stream");
2481 }
2482 else {
2483 byte_stream[n_bytes_in_stream++]=$2;
2484 }
2485 }
2486 | {}
2487 ;
2488
2489 kd_opt_name: STRING { $$=$1; }
2490 | { $$=NULL; }
2491 ;
2492
2493 kd_style_name_or_index: STRING { $$=find_style(&ki,$1); }
2494 | UNUMBER { if ($1>=ki.nstyles) yyerrorf("Invalid style index (%u/%d)",$1,ki.nstyles); $$=$1; }
2495 ;
2496
2497 kd_region_name_or_index: STRING { $$=find_region(&ki,$1); }
2498 | UNUMBER { if ($1>=ki.nregions) yyerrorf("Invalid region index (%u/%u)",$1,ki.nregions); $$=$1; }
2499 ;
2500
2501 kd_curve_name_or_index: STRING { $$=find_curve(&ki,$1); }
2502 | UNUMBER { if ($1>=ki.ncurves) yyerrorf("Invalid curve index (%u/%u)",$1,ki.ncurves); $$=$1; }
2503 ;
2504
2505 kd_motion_name_or_index: STRING { $$=find_motion(&ki,$1); }
2506 | UNUMBER { if ($1>=ki.nmotions) yyerrorf("Invalid motion index (%u/%u)",$1,ki.nmotions); $$=$1; }
2507 ;
2508
2509 kd_palette_name_or_index: STRING { $$=find_palette(&ki,$1); }
2510 | UNUMBER { if ($1>=ki.npalettes) yyerrorf("Invalid palette index (%u/%u)",$1,ki.npalettes); $$=$1; }
2511 ;
2512
2513 kd_bitmap_name_or_index: STRING { $$=find_bitmap(&ki,$1); }
2514 | UNUMBER { if ($1>=ki.nbitmaps) yyerrorf("Invalid bitmap index (%u/%u)",$1,ki.nbitmaps); $$=$1; }
2515 ;
2516
2517 kd_font_range_name_or_index: STRING { $$=find_font_range(&ki,$1); }
2518 | UNUMBER { if ($1>=ki.nfont_ranges) yyerrorf("Invalid font range index (%u/%u)",$1,ki.nfont_ranges); $$=$1; }
2519 ;
2520
2521 kd_font_mapping_name_or_index: STRING { $$=find_font_mapping(&ki,$1); }
2522 | UNUMBER { if ($1>=ki.nfont_mappings) yyerrorf("Invalid font mapping index (%u/%u)",$1,ki.nfont_mappings); $$=$1; }
2523 ;
2524
2525 kd_curve_def_name_or_index: kd_curve_name_or_index { reference_curve_from($1); }
2526 | { init_curve(); } '{' kd_curve_defs '}' {}
2527 | kd_curve_name_or_index { init_curve_from($1); } '{' kd_curve_defs '}' {}
2528 ;
2529
2530
2531 float: FLOAT { $$=$1; }
2532 | UNUMBER { $$=(kate_float)$1; }
2533 | NUMBER { $$=(kate_float)$1; }
2534 ;
2535
2536 bitmap_x_offset: UNUMBER { $$=$1; }
2537 | NUMBER { $$=$1; }
2538 | float '%' { $$=compute_bitmap_x_offset($1); }
2539 ;
2540
2541 bitmap_y_offset: UNUMBER { $$=$1; }
2542 | NUMBER { $$=$1; }
2543 | float '%' { $$=compute_bitmap_y_offset($1); }
2544 ;
2545
2546 timespec: UNUMBER ':' unumber60 ':' float60 { $$=$1*3600+$3*60+$5; }
2547 | UNUMBER ':' float60 { $$=$1*60+$3; }
2548 | float60 { $$=$1; }
2549 ;
2550
2551 kd_events: kd_events kd_event
2552 | {}
2553 ;
2554
2555 kd_event: EVENT { init_event(&kevent); } '{' kd_event_defs '}' {
2556 check_event(&kevent); kd_encode_text(&k,&kevent); clear_event(&kevent);
2557 }
2558 | EVENT { init_event(&kevent); } kd_event_defs {
2559 check_event(&kevent); kd_encode_text(&k,&kevent); clear_event(&kevent);
2560 }
2561 ;
2562
2563 kd_event_defs: kd_event_defs kd_event_def
2564 | {}
2565 ;
2566
2567 kd_event_def: ID UNUMBER { kd_encode_set_id(&k,$2); }
2568 | LANGUAGE STRING { kd_encode_set_language(&k,$2); }
2569 | DIRECTIONALITY directionality { CHECK_KATE_API_ERROR(kate_encode_set_text_directionality(&k,$2)); }
2570 | STARTS AT timespec { set_event_t0(&kevent,$3); }
2571 | ENDS AT timespec { set_event_t1(&kevent,$3); }
2572 | START TIME timespec { set_event_t0(&kevent,$3); }
2573 | END TIME timespec { set_event_t1(&kevent,$3); }
2574 | FROM timespec TO timespec { set_event_t0_t1(&kevent,$2,$4); }
2575 | DURATION timespec { set_event_duration(&kevent,$2); }
2576 | FROM timespec FOR timespec { set_event_t0(&kevent,$2); set_event_duration(&kevent,$4); }
2577 | timespec ARROW timespec { set_event_t0_t1(&kevent,$1,$3); }
2578 | REGION kd_region_name_or_index { set_event_region_index(&kevent,$2); }
2579 | REGION kd_region_name_or_index { init_region_from($2); } '{' kd_region_defs '}'
2580 { set_event_region(&kevent,&kregion); }
2581 | REGION { init_region(&kregion); } '{' kd_region_defs '}' { set_event_region(&kevent,&kregion); }
2582 | kd_optional_secondary STYLE kd_style_name_or_index
2583 { if ($1) set_event_secondary_style_index(&kevent,$3); else set_event_style_index(&kevent,$3); }
2584 | kd_optional_secondary STYLE kd_style_name_or_index {init_style_from($3); } '{' kd_style_defs '}'
2585 { if ($1) set_event_secondary_style(&kevent,&kstyle); else set_event_style(&kevent,&kstyle); }
2586 | kd_optional_secondary STYLE { init_style(&kstyle); } '{' kd_style_defs '}'
2587 { if ($1) set_event_secondary_style(&kevent,&kstyle); else set_event_style(&kevent,&kstyle); }
2588 | TEXT strings { set_event_text(&kevent,$2,0,0); kate_free($2); }
2589 | PRE TEXT strings { set_event_text(&kevent,$3,1,0); kate_free($3); }
2590 | MARKUP strings { set_event_text(&kevent,$2,0,1); kate_free($2); }
2591 | PRE MARKUP strings { set_event_text(&kevent,$3,1,1); kate_free($3); }
2592 | TEXT SOURCE STRING { set_event_text_from(&kevent,$3,0,0); }
2593 | PRE TEXT SOURCE STRING { set_event_text_from(&kevent,$4,1,0); }
2594 | MARKUP SOURCE STRING { set_event_text_from(&kevent,$3,0,1); }
2595 | PRE MARKUP SOURCE STRING { set_event_text_from(&kevent,$4,1,1); }
2596 | strings { set_event_text(&kevent,$1,0,0); kate_free($1); }
2597 | MOTION { init_motion(); } '{' kd_motion_defs '}' { kd_add_event_motion(kmotion); }
2598 | MOTION kd_motion_name_or_index { kd_add_event_motion_index($2); }
2599 | SIMPLE_TIMED_GLYPH_MARKER {init_simple_glyph_pointer_motion(); } '{' kd_simple_timed_glyph_marker_defs '}'
2600 { kd_finalize_simple_timed_glyph_motion(kmotion); kd_add_event_motion(kmotion); }
2601 | SIMPLE_TIMED_GLYPH_STYLE_MORPH {init_simple_glyph_pointer_motion(); } '{' kd_simple_timed_glyph_style_morph_defs '}'
2602 { kd_finalize_simple_timed_glyph_motion(kmotion); kd_add_event_motion(kmotion); }
2603 | FONT MAPPING kd_font_mapping_name_or_index { CHECK_KATE_API_ERROR(kate_encode_set_font_mapping_index(&k,$3)); }
2604 | PALETTE kd_palette_name_or_index { set_event_palette_index(&kevent,$2); }
2605 | PALETTE { init_palette(); } '{' kd_palette_defs '}' { set_event_palette(&kevent,kpalette.palette); }
2606 | BITMAP kd_bitmap_name_or_index { set_event_bitmap_index(&kevent,$2); }
2607 | BITMAP { init_bitmap(); } '{' kd_bitmap_defs '}' { set_event_bitmap(&kevent,kbitmap.bitmap); }
2608 | DEFINE LOCAL BITMAP kd_opt_name {init_bitmap();} '{' kd_bitmap_defs '}' { add_local_bitmap(&k,$4,kbitmap.bitmap); }
2609 | DEFINE LOCAL BITMAP kd_opt_name '=' kd_bitmap_name_or_index { add_local_bitmap_index(&k,$4,$6); }
2610 | META STRING '=' STRING { kd_add_event_meta($2,$4); }
2611 | META STRING '=' kd_meta_byte_stream_def { kd_add_event_meta_byte_stream($2); }
2612 ;
2613
2614 kd_meta_byte_stream_def: UNUMBER {init_byte_stream($1);} '{' kd_byte_stream '}' { $$=0; }
2615 ;
2616
2617 kd_optional_secondary: SECONDARY { $$=1; }
2618 | { $$=0; }
2619 ;
2620
2621 strings: strings '+' STRING { $$=catstrings($1,$3); }
2622 | STRING { $$=catstrings(NULL,$1); }
2623 ;
2624
2625 kd_motion_defs: kd_motion_defs kd_motion_def
2626 | {}
2627 ;
2628
2629 kd_motion_def: MAPPING kd_motion_mapping { set_motion_mapping(kmotion,$2,$2); }
2630 | MAPPING kd_motion_mapping kd_motion_mapping { set_motion_mapping(kmotion,$2,$3); }
2631 | SEMANTICS kd_motion_semantics { set_motion_semantics(kmotion,$2); }
2632 | CURVE kd_curve_def_name_or_index kd_optional_curve_duration { add_curve_to_motion(kmotion,$3); }
2633 | PERIODIC { kmotion->periodic=1; }
2634 ;
2635
2636 kd_optional_curve_duration: FOR float { $$=$2; }
2637 | FOR float '%' { $$=-$2/(kate_float)100.0; }
2638 | FOR float 'm' { $$=-$2/(kate_float)1000000.0; }
2639 | { $$=(kate_float)-1.0; }
2640 ;
2641
2642 kd_motion_mapping: NONE { $$=kate_motion_mapping_none; }
2643 | FRAME { $$=kate_motion_mapping_frame; }
2644 | REGION { $$=kate_motion_mapping_region; }
2645 | EVENT DURATION { $$=kate_motion_mapping_event_duration; }
2646 | BITMAP SIZE { $$=kate_motion_mapping_bitmap_size; }
2647 | USER UNUMBER {
2648 if ($2<kate_motion_mapping_user) yyerrorf("invalid value for user motion mapping (%u), should be 128 or more",$2);
2649 $$=(kate_motion_mapping)$2;
2650 }
2651 ;
2652
2653 kd_motion_semantics: TIME { $$=kate_motion_semantics_time; }
2654 | REGION POSITION { $$=kate_motion_semantics_region_position; }
2655 | REGION SIZE { $$=kate_motion_semantics_region_size; }
2656 | TEXT ALIGNMENT { $$=kate_motion_semantics_text_alignment_int; }
2657 | INTERNAL TEXT ALIGNMENT { $$=kate_motion_semantics_text_alignment_int; }
2658 | EXTERNAL TEXT ALIGNMENT { $$=kate_motion_semantics_text_alignment_ext; }
2659 | TEXT POSITION { $$=kate_motion_semantics_text_position; }
2660 | TEXT SIZE { $$=kate_motion_semantics_text_size; }
2661 | MARKER UNUMBER POSITION { $$=kd_get_marker_position_semantics($2); }
2662 | GLYPH POINTER UNUMBER { $$=kd_get_glyph_pointer_semantics($3); }
2663 | TEXT COLOR RG { $$=kate_motion_semantics_text_color_rg; }
2664 | TEXT COLOR BA { $$=kate_motion_semantics_text_color_ba; }
2665 | BACKGROUND COLOR RG { $$=kate_motion_semantics_background_color_rg; }
2666 | BACKGROUND COLOR BA { $$=kate_motion_semantics_background_color_ba; }
2667 | DRAW COLOR RG { $$=kate_motion_semantics_draw_color_rg; }
2668 | DRAW COLOR BA { $$=kate_motion_semantics_draw_color_ba; }
2669 | STYLE MORPH { $$=kate_motion_semantics_style_morph; }
2670 | TEXT PATH { $$=kate_motion_semantics_text_path; }
2671 | TEXT PATH SECTION { $$=kate_motion_semantics_text_path_section; }
2672 | DRAW { $$=kate_motion_semantics_draw; }
2673 | VISIBLE SECTION { $$=kate_motion_semantics_text_visible_section; }
2674 | 'z' { $$=kate_motion_semantics_z; }
2675 | HORIZONTAL MARGINS { $$=kate_motion_semantics_horizontal_margins; }
2676 | VERTICAL MARGINS { $$=kate_motion_semantics_vertical_margins; }
2677 | BITMAP POSITION { $$=kate_motion_semantics_bitmap_position; }
2678 | BITMAP SIZE { $$=kate_motion_semantics_bitmap_size; }
2679 | MARKER UNUMBER BITMAP { $$=kd_get_marker_bitmap_semantics($2); }
2680 | GLYPH POINTER UNUMBER BITMAP { $$=kd_get_glyph_pointer_bitmap_semantics($3); }
2681 | DRAW WIDTH { $$=kate_motion_semantics_draw_width; }
2682 | USER UNUMBER {
2683 if ($2<kate_motion_semantics_user) yyerrorf("invalid value for user motion semantics (%u), should be 128 or more",$2);
2684 $$=(kate_motion_semantics)$2;
2685 }
2686 ;
2687
2688 kd_simple_timed_glyph_marker_defs: kd_simple_timed_glyph_marker_defs kd_simple_timed_glyph_marker_def
2689 | {}
2690 ;
2691
2692 kd_simple_timed_glyph_marker_def: GLYPH POINTER UNUMBER { kmotion->semantics=get_glyph_pointer_offset($3); }
2693 | 'Y' MAPPING kd_motion_mapping { kmotion->y_mapping=$3; }
2694 | HEIGHT FROM float TO float { karaoke_base_height=$3; karaoke_top_height=$5; }
2695 | PAUSE FOR timespec { add_glyph_pause($3,(kate_float)0.0); }
2696 | GLYPH UNUMBER IN timespec { add_glyph_transition($2,$4,(kate_float)0.0,(kate_float)1.0,0,(kate_float)0.0); }
2697 | GLYPH UNUMBER AT timespec { add_glyph_transition($2,$4,(kate_float)0.0,(kate_float)1.0,1,(kate_float)0.0); }
2698 ;
2699
2700 kd_simple_timed_glyph_style_morph_defs: kd_simple_timed_glyph_style_morph_defs kd_simple_timed_glyph_style_morph_def
2701 | {}
2702 ;
2703
2704 kd_simple_timed_glyph_style_morph_def: GLYPH POINTER UNUMBER { kmotion->semantics=get_glyph_pointer_offset($3); }
2705 | FROM STYLE kd_style_name_or_index TO STYLE kd_style_name_or_index
2706 { set_style_morph(&kevent,$3,$6); }
2707 | PAUSE FOR timespec { add_glyph_pause($3,(kate_float)0.0); }
2708 | GLYPH UNUMBER IN timespec { add_glyph_transition($2,$4,(kate_float)0.0,(kate_float)0.0,0,(kate_float)1.0); }
2709 | GLYPH UNUMBER AT timespec { add_glyph_transition($2,$4,(kate_float)0.0,(kate_float)0.0,1,(kate_float)1.0); }
2710 | STRING IN timespec { add_glyph_transition_to_text($1,$3,(kate_float)0.0,(kate_float)0.0,0,(kate_float)1.0); }
2711 | STRING AT timespec { add_glyph_transition_to_text($1,$3,(kate_float)0.0,(kate_float)0.0,1,(kate_float)1.0); }
2712 ;
2713
2714 unumber60: UNUMBER { if ($1>59) yyerrorf("Value must be between 0 and 59, but is %u",$1); } { $$=$1; }
2715 ;
2716
2717 float60: float { if ($1<(kate_float)0.0 || $1>=(kate_float)60.0) yyerrorf("Value must be between 0 (inclusive) and 60 (exclusive), but is %f",$1); } { $$=$1; }
2718 ;
2719
2720 kd_opt_comma: ',' {}
2721 | {}
2722 ;
2723
2724 directionality: L2R_T2B { $$=kate_l2r_t2b; }
2725 | R2L_T2B { $$=kate_r2l_t2b; }
2726 | T2B_R2L { $$=kate_t2b_r2l; }
2727 | T2B_L2R { $$=kate_t2b_l2r; }
2728 ;
2729
2730 kd_font_range_defs: kd_font_range_defs kd_font_range_def
2731 | {}
2732 ;
2733
2734 kd_font_range_def: FIRST CODE POINT STRING { set_font_range_first_code_point_string($4); }
2735 | FIRST CODE POINT UNUMBER { set_font_range_first_code_point($4); }
2736 | LAST CODE POINT STRING { set_font_range_last_code_point_string($4); }
2737 | LAST CODE POINT UNUMBER { set_font_range_last_code_point($4); }
2738 | FIRST BITMAP kd_bitmap_name_or_index { set_font_range_first_bitmap($3); }
2739 ;
2740
2741 kd_font_mapping_defs: kd_font_mapping_defs kd_font_mapping_def
2742 | {}
2743 ;
2744
2745 kd_font_mapping_def: RANGE {init_font_range();} '{' kd_font_range_defs '}' { add_font_range_to_mapping(); }
2746 | RANGE kd_font_range_name_or_index { krange=ki.font_ranges[$2]; add_font_range_to_mapping(); }
2747 ;
2748
2749 %%
2750
2751