00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define KATE_INTERNAL
00011 #include "kate_internal.h"
00012
00013 #ifdef HAVE_STDLIB_H
00014 #include <stdlib.h>
00015 #endif
00016 #ifdef HAVE_STRING_H
00017 #include <string.h>
00018 #endif
00019 #include "kate/kate.h"
00020
00022 typedef struct kate_tracker_internal {
00023 size_t nglyphs;
00024 } kate_tracker_internal;
00025
00034 int kate_tracker_init(kate_tracker *kin,const kate_info *ki,kate_const kate_event *ev)
00035 {
00036 kate_tracker_internal *internal;
00037 const char *text;
00038 size_t rlen0;
00039
00040 if (!kin || !ki || !ev) return KATE_E_INVALID_PARAMETER;
00041
00042 internal=(kate_tracker_internal*)kate_malloc(sizeof(kate_tracker_internal));
00043 if (!internal) return KATE_E_OUT_OF_MEMORY;
00044
00045 kin->ki=ki;
00046 kin->event=ev;
00047 kin->internal=internal;
00048 kate_event_track(kin->event);
00049
00050 kin->internal->nglyphs=0;
00051 text=kin->event->text;
00052 rlen0=kin->event->len0;
00053 while (kate_text_get_character(kin->event->text_encoding,&text,&rlen0)>0)
00054 ++kin->internal->nglyphs;
00055
00056 return 0;
00057 }
00058
00066 int kate_tracker_clear(kate_tracker *kin)
00067 {
00068 if (!kin) return KATE_E_INVALID_PARAMETER;
00069 if (!kin->event) return KATE_E_INIT;
00070 if (!kin->internal) return KATE_E_INIT;
00071
00072 kate_free(kin->internal);
00073 kate_event_release(kin->event);
00074
00075 return 0;
00076 }
00077
00078 #define LERP(t,from,to) (((1-(t))*(from))+((t)*(to)))
00079
00091 int kate_tracker_morph_styles(kate_style *style,kate_float t,const kate_style *from,const kate_style *to)
00092 {
00093 if (!style || !from || !to) return KATE_E_INVALID_PARAMETER;
00094 if (t<(kate_float)-0.001 || t>(kate_float)1.001) return KATE_E_INVALID_PARAMETER;
00095
00096
00097 if (t<0) t=0;
00098 if (t>1) t=1;
00099
00100 #define MORPH(field) style->field=LERP(t,from->field,to->field)
00101 #define MORPHINT(field) style->field=(int)((kate_float)0.5+LERP(t,from->field,to->field))
00102 MORPH(halign);
00103 MORPH(valign);
00104 MORPHINT(text_color.r);
00105 MORPHINT(text_color.g);
00106 MORPHINT(text_color.b);
00107 MORPHINT(text_color.a);
00108 MORPHINT(background_color.r);
00109 MORPHINT(background_color.g);
00110 MORPHINT(background_color.b);
00111 MORPHINT(background_color.a);
00112 MORPHINT(draw_color.r);
00113 MORPHINT(draw_color.g);
00114 MORPHINT(draw_color.b);
00115 MORPHINT(draw_color.a);
00116 MORPHINT(font_metric);
00117 MORPH(font_width);
00118 MORPH(font_height);
00119 MORPHINT(margin_metric);
00120 MORPH(left_margin);
00121 MORPH(top_margin);
00122 MORPH(right_margin);
00123 MORPH(bottom_margin);
00124 MORPHINT(bold);
00125 MORPHINT(italics);
00126 MORPHINT(underline);
00127 MORPHINT(strike);
00128 MORPHINT(justify);
00129 MORPHINT(wrap_mode);
00130 style->font=(t<(kate_float)0.5)?from->font:to->font;
00131 #undef MORPHINT
00132 #undef MORPH
00133
00134 return 0;
00135 }
00136
00148 int kate_tracker_remap(const kate_tracker *kin,kate_motion_mapping x_mapping,kate_motion_mapping y_mapping,kate_float *x,kate_float *y)
00149 {
00150 if (!kin || !x || !y) return KATE_E_INVALID_PARAMETER;
00151
00152 switch (x_mapping) {
00153 case kate_motion_mapping_none:
00154
00155 break;
00156 case kate_motion_mapping_frame:
00157 *x=kin->frame_x+(*x)*kin->frame_w;
00158 break;
00159 case kate_motion_mapping_window:
00160 *x=(*x)*kin->window_w;
00161 break;
00162 case kate_motion_mapping_region:
00163 *x=kin->region_x+(*x)*kin->region_w;
00164 break;
00165 case kate_motion_mapping_event_duration:
00166 *x=(*x)*(kin->event->end_time-kin->event->start_time);
00167 break;
00168 case kate_motion_mapping_bitmap_size:
00169 if (!kin->event->bitmap) return KATE_E_INVALID_PARAMETER;
00170 *x=(*x)*kin->event->bitmap->width;
00171 break;
00172 default:
00173
00174 return KATE_E_INVALID_PARAMETER;
00175 }
00176
00177 switch (y_mapping) {
00178 case kate_motion_mapping_none:
00179
00180 break;
00181 case kate_motion_mapping_frame:
00182 *y=kin->frame_y+(*y)*kin->frame_h;
00183 break;
00184 case kate_motion_mapping_window:
00185 *y=(*y)*kin->window_h;
00186 break;
00187 case kate_motion_mapping_region:
00188 *y=kin->region_y+(*y)*kin->region_h;
00189 break;
00190 case kate_motion_mapping_event_duration:
00191 *y=(*y)*(kin->event->end_time-kin->event->start_time);
00192 break;
00193 case kate_motion_mapping_bitmap_size:
00194 if (!kin->event->bitmap) return KATE_E_INVALID_PARAMETER;
00195 *y=(*y)*kin->event->bitmap->height;
00196 break;
00197 default:
00198
00199 return KATE_E_INVALID_PARAMETER;
00200 }
00201
00202 return 0;
00203 }
00204
00205 static const kate_motion *kate_tracker_find_motion(const kate_tracker *kin,kate_motion_semantics semantics)
00206 {
00207 const kate_event *ev;
00208 const kate_motion *km;
00209 size_t n;
00210
00211 if (!kin || !kin->event) return NULL;
00212
00213 ev=kin->event;
00214 for (n=0;n<ev->nmotions;++n) {
00215 km=ev->motions[n];
00216 if (km->semantics==semantics) return km;
00217 }
00218
00219 return NULL;
00220 }
00221
00235 int kate_tracker_update_property_at_duration(const kate_tracker *kin,kate_float duration,kate_float t,kate_motion_semantics semantics,kate_float *x,kate_float *y)
00236 {
00237 const kate_motion *km;
00238 int ret;
00239
00240 if (!kin || !x || !y) return KATE_E_INVALID_PARAMETER;
00241
00242 km=kate_tracker_find_motion(kin,semantics);
00243 if (km) {
00244 ret=kate_motion_get_point(km,duration,t,x,y);
00245 if (ret<0) return ret;
00246 if (ret==0) {
00247 ret=kate_tracker_remap(kin,km->x_mapping,km->y_mapping,x,y);
00248 if (ret<0) return ret;
00249 return 0;
00250 }
00251 return 1;
00252 }
00253 return 1;
00254 }
00255
00256 static int kate_tracker_update_property_at(const kate_tracker *kin,kate_float t,kate_motion_semantics semantics,kate_float *x,kate_float *y)
00257 {
00258 #if 1
00259 kate_float duration=kin->event->end_time-kin->event->start_time;
00260 return kate_tracker_update_property_at_duration(kin,duration,t,semantics,x,y);
00261 #else
00262 const kate_motion *km;
00263 int ret;
00264
00265 if (!kin || !x || !y) return KATE_E_INVALID_PARAMETER;
00266
00267 km=kate_tracker_find_motion(kin,semantics);
00268 if (km) {
00269
00270 kate_float duration=kin->event->end_time-kin->event->start_time;
00271 ret=kate_motion_get_point(km,duration,t,x,y);
00272 if (ret<0) return ret;
00273 if (ret==0) {
00274 ret=kate_tracker_remap(kin,km->x_mapping,km->y_mapping,x,y);
00275 if (ret<0) return ret;
00276 return 0;
00277 }
00278 return 1;
00279 }
00280 return 1;
00281 #endif
00282 }
00283
00284 static int kate_tracker_update_property(const kate_tracker *kin,kate_motion_semantics semantics,kate_float *px,kate_float *py)
00285 {
00286 if (!kin) return KATE_E_INVALID_PARAMETER;
00287 return kate_tracker_update_property_at(kin,kin->t,semantics,px,py);
00288 }
00289
00290 static unsigned char kate_float_to_color_component(kate_float c)
00291 {
00292 int v=(int)(c+(kate_float)0.5);
00293 if (v<0) v=0;
00294 if (v>255) v=255;
00295 return v;
00296 }
00297
00298 static const kate_bitmap *kate_tracker_find_bitmap(const kate_tracker *kin,kate_float frame)
00299 {
00300 size_t idx=(size_t)(frame+(kate_float)0.5);
00301 if (kin->event->nbitmaps>0) {
00302 if (idx<kin->event->nbitmaps) {
00303 return kin->event->bitmaps[idx];
00304 }
00305 }
00306 else {
00307 if (idx<kin->ki->nbitmaps) {
00308 return kin->ki->bitmaps[idx];
00309 }
00310 }
00311 return NULL;
00312 }
00313
00328 int kate_tracker_update(kate_tracker *kin,kate_float t,int window_w,int window_h,int frame_x,int frame_y,int frame_w,int frame_h)
00329 {
00330 const kate_event *ev;
00331 const kate_region *kr;
00332 const kate_style *ks;
00333 const kate_motion *km;
00334 size_t n;
00335 int ret;
00336 kate_float r,g,b,a;
00337 kate_float dummy;
00338 kate_float frame;
00339
00340 if (!kin) return KATE_E_INVALID_PARAMETER;
00341 if (!kin->event) return KATE_E_INIT;
00342 if (t<0) return KATE_E_INVALID_PARAMETER;
00343 if (frame_w<0 || frame_h<0) return KATE_E_INVALID_PARAMETER;
00344
00345 ev=kin->event;
00346 kin->t=t;
00347 memset(&kin->has,0,sizeof(kin->has));
00348
00349 kin->window_w=window_w;
00350 kin->window_h=window_h;
00351 kin->frame_x=frame_x;
00352 kin->frame_y=frame_y;
00353 kin->frame_w=frame_w;
00354 kin->frame_h=frame_h;
00355
00356
00357 kr=ev->region;
00358
00359
00360 ks=ev->style;
00361 if (!ks && kr && kr->style>=0) ks=kin->ki->styles[kr->style];
00362
00363
00364 kin->region_x=kin->region_y=kin->region_w=kin->region_h=0;
00365 if (kr) {
00366 switch (kr->metric) {
00367 case kate_percentage:
00368 kin->region_x=kr->x*frame_w/(kate_float)100;
00369 kin->region_y=kr->y*frame_h/(kate_float)100;
00370 kin->region_w=kr->w*frame_w/(kate_float)100;
00371 kin->region_h=kr->h*frame_h/(kate_float)100;
00372 break;
00373 case kate_millionths:
00374 kin->region_x=kr->x*(kate_int64_t)frame_w/(kate_float)1000000;
00375 kin->region_y=kr->y*(kate_int64_t)frame_h/(kate_float)1000000;
00376 kin->region_w=kr->w*(kate_int64_t)frame_w/(kate_float)1000000;
00377 kin->region_h=kr->h*(kate_int64_t)frame_h/(kate_float)1000000;
00378 break;
00379 case kate_pixel:
00380 kin->region_x=kr->x;
00381 kin->region_y=kr->y;
00382 kin->region_w=kr->w;
00383 kin->region_h=kr->h;
00384 break;
00385 default:
00386 return KATE_E_INVALID_PARAMETER;
00387 break;
00388 }
00389
00390 kin->has.region=1;
00391 }
00392
00393 if (ks) {
00394 kin->text_color=ks->text_color;
00395 kin->background_color=ks->background_color;
00396 kin->draw_color=ks->draw_color;
00397
00398 kin->has.text_color=1;
00399 kin->has.background_color=1;
00400 kin->has.draw_color=1;
00401
00402 kin->text_halign=ks->halign;
00403 kin->text_valign=ks->valign;
00404
00405 kin->has.text_alignment_int=1;
00406 }
00407
00408
00409 if (!kin->event->nmotions) return 0;
00410
00411
00412
00413
00414 ret=kate_tracker_update_property(kin,kate_motion_semantics_time,&t,&dummy);
00415 if (ret==0) {
00416
00417
00418 if (t<0) t=0;
00419
00420
00421 kin->t=t;
00422 }
00423
00424
00425 ret=kate_tracker_update_property(kin,kate_motion_semantics_z,&kin->z,&dummy);
00426 if (ret==0) kin->has.z=1;
00427
00428
00429 if (kr) {
00430 ret=kate_tracker_update_property(kin,kate_motion_semantics_region_position,&kin->region_x,&kin->region_y);
00431 if (ret==0) kin->has.region=1;
00432 }
00433
00434
00435 if (kr) {
00436 ret=kate_tracker_update_property(kin,kate_motion_semantics_region_size,&kin->region_w,&kin->region_h);
00437 if (ret==0) kin->has.region=1;
00438 }
00439
00440
00441 if (kr) {
00442 ret=kate_tracker_update_property(kin,kate_motion_semantics_text_visible_section,&kin->visible_x,&kin->visible_y);
00443 if (ret==0) kin->has.visible_section=1;
00444 }
00445
00446
00447 km=kate_tracker_find_motion(kin,kate_motion_semantics_text_path);
00448 if (km) {
00449 kin->has.path=1;
00450 kin->path_start=0;
00451 kin->path_end=1;
00452 ret=kate_tracker_update_property(kin,kate_motion_semantics_text_path_section,&kin->path_start,&kin->path_end);
00453 }
00454
00455
00456 km=kate_tracker_find_motion(kin,kate_motion_semantics_style_morph);
00457 if (km) {
00458 kate_float morphing;
00459 kate_float duration=kin->event->end_time-kin->event->start_time;
00460 ret=kate_motion_get_point(km,duration,kin->t,&morphing,&dummy);
00461 if (ret==0) {
00462 kate_style style;
00463 ret=kate_tracker_morph_styles(&style,morphing,ev->style,ev->secondary_style);
00464 if (ret==0) {
00465 kin->text_halign=style.halign;
00466 kin->text_valign=style.valign;
00467 kin->text_color=style.text_color;
00468 kin->background_color=style.background_color;
00469 kin->draw_color=style.draw_color;
00470 kin->left_margin=style.left_margin;
00471 kin->top_margin=style.top_margin;
00472 kin->right_margin=style.right_margin;
00473 kin->bottom_margin=style.bottom_margin;
00474
00475
00476 kin->has.text_alignment_int=1;
00477 kin->has.text_color=1;
00478 kin->has.background_color=1;
00479 kin->has.draw_color=1;
00480 kin->has.hmargins=1;
00481 kin->has.vmargins=1;
00482 }
00483 }
00484 }
00485
00486
00487 ret=kate_tracker_update_property(kin,kate_motion_semantics_horizontal_margins,&kin->left_margin,&kin->right_margin);
00488 if (ret==0) kin->has.hmargins=1;
00489 ret=kate_tracker_update_property(kin,kate_motion_semantics_vertical_margins,&kin->top_margin,&kin->bottom_margin);
00490 if (ret==0) kin->has.vmargins=1;
00491
00492
00493 ret=kate_tracker_update_property(kin,kate_motion_semantics_text_alignment_int,&kin->text_halign,&kin->text_valign);
00494 if (ret==0) kin->has.text_alignment_int=1;
00495 ret=kate_tracker_update_property(kin,kate_motion_semantics_text_alignment_ext,&kin->text_halign,&kin->text_valign);
00496 if (ret==0) {
00497 kin->has.text_alignment_int=0;
00498 kin->has.text_alignment_ext=1;
00499 }
00500
00501
00502 ret=kate_tracker_update_property(kin,kate_motion_semantics_bitmap_position,&kin->bitmap_x,&kin->bitmap_y);
00503 if (ret==0) kin->has.bitmap_pos=1;
00504
00505
00506 ret=kate_tracker_update_property(kin,kate_motion_semantics_bitmap_size,&kin->bitmap_size_x,&kin->bitmap_size_y);
00507 if (ret==0) kin->has.bitmap_size=1;
00508
00509
00510 ret=kate_tracker_update_property(kin,kate_motion_semantics_text_position,&kin->text_x,&kin->text_y);
00511 if (ret==0) kin->has.text_pos=1;
00512
00513
00514 ret=kate_tracker_update_property(kin,kate_motion_semantics_text_size,&kin->text_size_x,&kin->text_size_y);
00515 if (ret==0) kin->has.text_size=1;
00516
00517
00518 for (n=0;n<4;++n) {
00519 kate_motion_semantics semantics=(kate_motion_semantics)(kate_motion_semantics_glyph_pointer_1+n);
00520 ret=kate_tracker_update_property(kin,semantics,&kin->glyph_pointer[n],&kin->glyph_height[n]);
00521 if (ret==0) {
00522 kin->has.glyph_pointer|=(1<<n);
00523
00524 semantics=(kate_motion_semantics)(kate_motion_semantics_glyph_pointer_1_bitmap+n);
00525 ret=kate_tracker_update_property(kin,semantics,&frame,&dummy);
00526 if (ret==0) {
00527 const kate_bitmap *kb=kate_tracker_find_bitmap(kin,frame);
00528 if (kb) {
00529 kin->glyph_pointer_bitmap[n]=kb;
00530 kin->has.glyph_pointer_bitmap|=(1<<n);
00531 }
00532 }
00533 }
00534 }
00535
00536
00537 for (n=0;n<4;++n) {
00538 kate_motion_semantics semantics=(kate_motion_semantics)(kate_motion_semantics_marker1_position+n);
00539 ret=kate_tracker_update_property(kin,semantics,&kin->marker_x[n],&kin->marker_y[n]);
00540 if (ret==0) {
00541 kin->has.marker_pos|=(1<<n);
00542
00543 semantics=(kate_motion_semantics)(kate_motion_semantics_marker1_bitmap+n);
00544 ret=kate_tracker_update_property(kin,semantics,&frame,&dummy);
00545 if (ret==0) {
00546 const kate_bitmap *kb=kate_tracker_find_bitmap(kin,frame);
00547 if (kb) {
00548 kin->marker_bitmap[n]=kb;
00549 kin->has.marker_bitmap|=(1<<n);
00550 }
00551 }
00552 }
00553 }
00554
00555
00556 ret=kate_tracker_update_property(kin,kate_motion_semantics_draw,&kin->draw_x,&kin->draw_y);
00557 if (ret==0) kin->has.draw=1;
00558
00559
00560 ret=kate_tracker_update_property(kin,kate_motion_semantics_text_color_rg,&r,&g);
00561 if (ret==0) {
00562 kin->text_color.r=kate_float_to_color_component(r);
00563 kin->text_color.g=kate_float_to_color_component(g);
00564 kin->has.text_color=1;
00565 }
00566 ret=kate_tracker_update_property(kin,kate_motion_semantics_text_color_ba,&b,&a);
00567 if (ret==0) {
00568 kin->text_color.b=kate_float_to_color_component(b);
00569 kin->text_color.a=kate_float_to_color_component(a);
00570 kin->has.text_color=1;
00571 }
00572
00573 ret=kate_tracker_update_property(kin,kate_motion_semantics_background_color_rg,&r,&g);
00574 if (ret==0) {
00575 kin->background_color.r=kate_float_to_color_component(r);
00576 kin->background_color.g=kate_float_to_color_component(g);
00577 kin->has.background_color=1;
00578 }
00579 ret=kate_tracker_update_property(kin,kate_motion_semantics_background_color_ba,&b,&a);
00580 if (ret==0) {
00581 kin->background_color.b=kate_float_to_color_component(b);
00582 kin->background_color.a=kate_float_to_color_component(a);
00583 kin->has.background_color=1;
00584 }
00585
00586 ret=kate_tracker_update_property(kin,kate_motion_semantics_draw_color_rg,&r,&g);
00587 if (ret==0) {
00588 kin->draw_color.r=kate_float_to_color_component(r);
00589 kin->draw_color.g=kate_float_to_color_component(g);
00590 kin->has.draw_color=1;
00591 }
00592 ret=kate_tracker_update_property(kin,kate_motion_semantics_draw_color_ba,&b,&a);
00593 if (ret==0) {
00594 kin->draw_color.b=kate_float_to_color_component(b);
00595 kin->draw_color.a=kate_float_to_color_component(a);
00596 kin->has.draw_color=1;
00597 }
00598
00599
00600 ret=kate_tracker_update_property(kin,kate_motion_semantics_draw_width,&kin->draw_width,&dummy);
00601 if (ret==0) kin->has.draw_width=1;
00602
00603 return 0;
00604 }
00605
00614 int kate_tracker_get_text_path_position(kate_tracker *kin,size_t glyph,int *x,int *y)
00615 {
00616 kate_float t;
00617 kate_float dx,dy;
00618 int ret;
00619
00620 if (!kin || !x || !y) return KATE_E_INVALID_PARAMETER;
00621 if (glyph>=kin->internal->nglyphs) return KATE_E_INVALID_PARAMETER;
00622 if (!kin->has.path) return KATE_E_INVALID_PARAMETER;
00623
00624 t=0;
00625 if (kin->internal->nglyphs>1) {
00626 t=kin->path_start+glyph*(kin->path_end-kin->path_start)/(kin->internal->nglyphs-1);
00627 }
00628 ret=kate_tracker_update_property_at_duration(kin,1,t,kate_motion_semantics_text_path,&dx,&dy);
00629 if (ret==0) {
00630 *x=(int)(dx+(kate_float)0.5);
00631 *y=(int)(dy+(kate_float)0.5);
00632 }
00633
00634 return ret;
00635 }
00636