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