- Main Page
- Related Pages
- Data Structures
- Files
- Examples

- File List

# /home/v/Kate/WORK_TREES/kate-sorceress-backup/v/src/kate/src/kate_tracker.c

    00001 /* Copyright (C) 2008 Vincent Penquerc'h.
    00002    This file is part of the Kate codec library.
    00003    Written by Vincent Penquerc'h.
    00004
    00005    Use, distribution and reproduction of this library is governed
    00006    by a BSD style source license included with this source in the
    00007    file 'COPYING'. Please read these terms before distributing. */
    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   /* clamp, just in case */
    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); /* doesn't make much sense, caveat streamor */
    00117   MORPH(font_width);
    00118   MORPH(font_height);
    00119   MORPHINT(margin_metric); /* doesn't make much sense, caveat streamor */
    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); /* doesn't make much sense, caveat streamor */
    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       /* nothing to do */
    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       /* unknown mapping */
    00174       return KATE_E_INVALID_PARAMETER;
    00175   }
    00176
    00177   switch (y_mapping) {
    00178     case kate_motion_mapping_none:
    00179       /* nothing to do */
    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       /* unknown mapping */
    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; /* positive means no error, but no curve at that point */
    00252   }
    00253   return 1; /* positive means no error, but nothing found either */
    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     /* TODO: could be precalculated */
    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; /* positive means no error, but no curve at that point */
    00279   }
    00280   return 1; /* positive means no error, but nothing found either */
    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   /* find out which region we're in, if any */
    00357   kr=ev->region;
    00358
    00359   /* find out which style we have, if any */
    00360   ks=ev->style;
    00361   if (!ks && kr && kr->style>=0) ks=kin->ki->styles[kr->style]; /* regions can have a default style */
    00362
    00363   /* start off with the event attributes */
    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: /* use 64 bit arithmetic to avoid overflow */
    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     /* we already have a valid region */
    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     /* we already have valid text/background/draw colors */
    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     /* we already have internal alignment */
    00405     kin->has.text_alignment_int=1;
    00406   }
    00407
    00408   /* if we have no motions, go no further */
    00409   if (!kin->event->nmotions) return 0;
    00410
    00411   /* TODO: think about the consequences of this wrt continuations */
    00412
    00413   /* alter the flow of time */
    00414   ret=kate_tracker_update_property(kin,kate_motion_semantics_time,&t,&dummy);
    00415   if (ret==0) {
    00416     /* t should be left within 0-duration */
    00417     /* clamp, just in case */
    00418     if (t<0) t=0;
    00419
    00420     /* jump in time for the remainder of the lookups */
    00421     kin->t=t;
    00422   }
    00423
    00424   /* update Z */
    00425   ret=kate_tracker_update_property(kin,kate_motion_semantics_z,&kin->z,&dummy);
    00426   if (ret==0) kin->has.z=1;
    00427
    00428   /* update region position */
    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   /* update region size */
    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   /* update text visible section */
    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   /* update text path section */
    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   /* update style morphing */
    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         /* we get everything that's in a style here */
    00475         /* those can be overridden afterwards by an alignment/color/etc motion */
    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   /* update margins */
    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   /* update text alignment */
    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; /* external alignment override internal (the default) */
    00498     kin->has.text_alignment_ext=1;
    00499   }
    00500
    00501   /* update bitmap position */
    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   /* update bitmap size */
    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   /* update text position */
    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   /* update text size */
    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   /* update glyph pointers */
    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       /* we don't have to bother looking for a bitmap frame if there's no glyph pointer */
    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   /* update marker position */
    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       /* we don't have to bother looking for a bitmap frame if there's no marker position */
    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   /* update draw position */
    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   /* update colors */
    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   /* update draw width */
    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