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

- File List

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

    00001 /* Copyright (C) 2008, 2009 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
    00029 int kate_info_init(kate_info *ki)
    00030 {
    00031   if (!ki) return KATE_E_INVALID_PARAMETER;
    00032
    00033   ki->bitstream_version_major=KATE_BITSTREAM_VERSION_MAJOR;
    00034   ki->bitstream_version_minor=KATE_BITSTREAM_VERSION_MINOR;
    00035
    00036   ki->num_headers=0;
    00037
    00038   /* default to a sensible granule encoding */
    00039   ki->granule_shift=32;
    00040   ki->gps_numerator=1000;
    00041   ki->gps_denominator=1;
    00042
    00043   ki->text_encoding=kate_utf8;
    00044   ki->text_directionality=kate_l2r_t2b;
    00045   ki->text_markup_type=kate_markup_none;
    00046
    00047   ki->language=NULL;
    00048   ki->category=NULL;
    00049
    00050   ki->nregions=0;
    00051   ki->regions=NULL;
    00052   ki->nstyles=0;
    00053   ki->styles=NULL;
    00054   ki->ncurves=0;
    00055   ki->curves=NULL;
    00056   ki->nmotions=0;
    00057   ki->motions=NULL;
    00058   ki->npalettes=0;
    00059   ki->palettes=NULL;
    00060   ki->nbitmaps=0;
    00061   ki->bitmaps=NULL;
    00062   ki->nfont_ranges=0;
    00063   ki->font_ranges=NULL;
    00064   ki->nfont_mappings=0;
    00065   ki->font_mappings=NULL;
    00066
    00067   ki->original_canvas_width=0;
    00068   ki->original_canvas_height=0;
    00069
    00070   ki->remove_markup=0;
    00071   ki->no_limits=0;
    00072   ki->probe=0;
    00073
    00074   return 0;
    00075 }
    00076
    00077 static void kate_make_fraction(kate_float resolution,kate_uint32_t *numerator,kate_uint32_t *denominator)
    00078 {
    00079   if (resolution<1) {
    00080     *numerator=(kate_uint32_t)(1000/resolution+(kate_float)0.5);
    00081     *denominator=1000;
    00082   }
    00083   else {
    00084     *numerator=1000;
    00085     *denominator=(kate_uint32_t)(resolution*1000+(kate_float)0.5);
    00086   }
    00087 }
    00088
    00100 int kate_info_set_granule_encoding(kate_info *ki,kate_float resolution,kate_float max_length,kate_float max_event_lifetime)
    00101 {
    00102   kate_float offset_granules;
    00103   unsigned char offset_bits,bits;
    00104   kate_float base_min_resolution;
    00105
    00106   if (!ki || resolution<=0 || max_event_lifetime<0) return KATE_E_INVALID_PARAMETER;
    00107
    00108   offset_granules=max_event_lifetime/resolution;
    00109   offset_bits=0;
    00110   while (offset_granules>=1) {
    00111     ++offset_bits;
    00112     if (offset_bits>=64) return KATE_E_BAD_GRANULE;
    00113     offset_granules/=2;
    00114   }
    00115
    00116   base_min_resolution=max_length;
    00117   bits=offset_bits;
    00118   while (bits<62) {
    00119     ++bits;
    00120     base_min_resolution/=2;
    00121   }
    00122
    00123   ki->granule_shift=offset_bits;
    00124   kate_make_fraction(resolution,&ki->gps_numerator,&ki->gps_denominator);
    00125
    00126   if (base_min_resolution<=resolution) {
    00127     /* we can represent the required encoding */
    00128     return 0;
    00129   }
    00130   else {
    00131     /* we cannot represent the required encoding */
    00132     return KATE_E_BAD_GRANULE;
    00133   }
    00134 }
    00135
    00136 static int kate_replace_string(char **sptr,const char *s,size_t len)
    00137 {
    00138   char *l=NULL;
    00139   int ret;
    00140
    00141   if (!sptr) return KATE_E_INVALID_PARAMETER;
    00142
    00143   ret=kate_check_add_overflow(len,1,NULL);
    00144   if (ret<0) return ret;
    00145
    00146   if (s) {
    00147     l=(char*)kate_malloc(len+1);
    00148     if (!l) return KATE_E_OUT_OF_MEMORY;
    00149     memcpy(l,s,len);
    00150     l[len]=0;
    00151   }
    00152
    00153   if (*sptr) kate_free(*sptr);
    00154   *sptr=l;
    00155
    00156   return 0;
    00157 }
    00158
    00176 int kate_info_set_language(kate_info *ki,const char *language)
    00177 {
    00178   int ret;
    00179   size_t len;
    00180   size_t new_len;
    00181   const char *sep;
    00182   int truncated;
    00183
    00184   if (!ki) return KATE_E_INVALID_PARAMETER;
    00185   if (!language) return KATE_E_INVALID_PARAMETER;
    00186
    00187   /* special case for empty string */
    00188   if (!*language) {
    00189     return kate_replace_string(&ki->language,language,0);
    00190   }
    00191
    00192   /* basic validation of allowed characters - won't catch all */
    00193   for (sep=language;*sep;++sep) {
    00194     int c=*sep;
    00195     if (c>='A' && c<='Z') continue;
    00196     if (c>='a' && c<='z') continue;
    00197     if (c>='0' && c<='9') continue;
    00198     if (c=='-' || c=='_') continue;
    00199     return KATE_E_INVALID_PARAMETER;
    00200   }
    00201
    00202   /* simple validity - the first tag must be 2 characters */
    00203   sep=strpbrk(language,"-_");
    00204   if (!sep) sep=language+strlen(language);
    00205   if (sep-language==0 || sep-language>3) return KATE_E_INVALID_PARAMETER;
    00206
    00207   /* if the tag is too long, it has to be truncated; while we still have space,
    00208      find the next - or _ following a tag of more than one character, and see
    00209      if we can fit it */
    00210   len=0;
    00211   new_len=0;
    00212   truncated=1;
    00213   while (truncated) {
    00214     size_t prev_new_len=new_len;
    00215     sep=strpbrk(language+new_len,"-_");
    00216     if (sep) {
    00217       new_len=sep-language;
    00218     }
    00219     else {
    00220       /* not found, gobble the remainder of the string */
    00221       new_len=strlen(language);
    00222       truncated=0;
    00223     }
    00224     /* maximum length of a subtag is 8 characters */
    00225     if (new_len-prev_new_len>8) {
    00226       return KATE_E_INVALID_PARAMETER;
    00227     }
    00228     if (new_len>15) {
    00229       /* we can't fit this new tag */
    00230       truncated=1;
    00231       break;
    00232     }
    00233     /* one or less character tags aren't allowed as the last tag */
    00234     if (new_len-prev_new_len>=2) {
    00235       /* so more than this is OK to keep */
    00236       len=new_len;
    00237     }
    00238     else {
    00239       /* but less we ignore if we have more to go, but complain if we're at the end */
    00240       if (!truncated) return KATE_E_INVALID_PARAMETER;
    00241     }
    00242     /* if we need another go, skip the separator */
    00243     ++new_len;
    00244   }
    00245
    00246   if (len<=1) {
    00247     /* we can't fit any subtag, or the first tag is less than 2 characters long */
    00248     return KATE_E_INVALID_PARAMETER;
    00249   }
    00250
    00251   ret=kate_replace_string(&ki->language,language,len);
    00252   if (ret<0) return ret;
    00253
    00254   return truncated?1:0;
    00255 }
    00256
    00265 int kate_info_set_text_directionality(kate_info *ki,kate_text_directionality text_directionality)
    00266 {
    00267   if (!ki) return KATE_E_INVALID_PARAMETER;
    00268   ki->text_directionality=text_directionality;
    00269   return 0;
    00270 }
    00271
    00287 int kate_info_set_category(kate_info *ki,const char *category)
    00288 {
    00289   if (!ki) return KATE_E_INVALID_PARAMETER;
    00290   if (!category) return KATE_E_INVALID_PARAMETER;
    00291   if (strlen(category)>15) return KATE_E_LIMIT;
    00292   return kate_replace_string(&ki->category,category,strlen(category));
    00293 }
    00294
    00303 int kate_info_set_markup_type(kate_info *ki,kate_markup_type text_markup_type)
    00304 {
    00305   if (!ki) return KATE_E_INVALID_PARAMETER;
    00306   ki->text_markup_type=text_markup_type;
    00307   return 0;
    00308 }
    00309
    00319 int kate_info_set_original_canvas_size(kate_info *ki,size_t width,size_t height)
    00320 {
    00321   if (!ki) return KATE_E_INVALID_PARAMETER;
    00322   ki->original_canvas_width=width;
    00323   ki->original_canvas_height=height;
    00324   return 0;
    00325 }
    00326
    00327 static int kate_info_add_item(kate_info *ki,size_t *nitems,void ***items,void *item)
    00328 {
    00329   void **newitems;
    00330   int ret;
    00331
    00332   if (!ki || !nitems || !items || !item) return KATE_E_INVALID_PARAMETER;
    00333
    00334   ret=kate_check_add_overflow(*nitems,1,NULL);
    00335   if (ret<0) return ret;
    00336
    00337   newitems=(void**)kate_checked_realloc(*items,(*nitems)+1,sizeof(void*));
    00338   if (!newitems) return KATE_E_OUT_OF_MEMORY;
    00339   *items=newitems;
    00340   newitems[*nitems]=item;
    00341   ++*nitems;
    00342
    00343   return 0;
    00344 }
    00345
    00354 int kate_info_add_region(kate_info *ki,kate_region *kr)
    00355 {
    00356   return kate_info_add_item(ki,&ki->nregions,(void***)(char*)&ki->regions,kr);
    00357 }
    00358
    00368 int kate_info_add_style(kate_info *ki,kate_style *ks)
    00369 {
    00370   return kate_info_add_item(ki,&ki->nstyles,(void***)(char*)&ki->styles,ks);
    00371 }
    00372
    00381 int kate_info_add_curve(kate_info *ki,kate_curve *kc)
    00382 {
    00383   return kate_info_add_item(ki,&ki->ncurves,(void***)(char*)&ki->curves,kc);
    00384 }
    00385
    00394 int kate_info_add_motion(kate_info *ki,kate_motion *km)
    00395 {
    00396   return kate_info_add_item(ki,&ki->nmotions,(void***)(char*)&ki->motions,km);
    00397 }
    00398
    00407 int kate_info_add_palette(kate_info *ki,kate_palette *kp)
    00408 {
    00409   return kate_info_add_item(ki,&ki->npalettes,(void***)(char*)&ki->palettes,kp);
    00410 }
    00411
    00420 int kate_info_add_bitmap(kate_info *ki,kate_bitmap *kb)
    00421 {
    00422   return kate_info_add_item(ki,&ki->nbitmaps,(void***)(char*)&ki->bitmaps,kb);
    00423 }
    00424
    00433 int kate_info_add_font_range(kate_info *ki,kate_font_range *kfr)
    00434 {
    00435   return kate_info_add_item(ki,&ki->nfont_ranges,(void***)(char*)&ki->font_ranges,kfr);
    00436 }
    00437
    00446 int kate_info_add_font_mapping(kate_info *ki,kate_font_mapping *kfm)
    00447 {
    00448   return kate_info_add_item(ki,&ki->nfont_mappings,(void***)(char*)&ki->font_mappings,kfm);
    00449 }
    00450
    00467 int kate_info_matches_language(const kate_info *ki,const char *language)
    00468 {
    00469   char *sep0,*sep1;
    00470   size_t bytes;
    00471   if (!ki) return KATE_E_INVALID_PARAMETER;
    00472
    00473   if (!language || !*language) return 2; /* if we ask for "any" language, we partially match */
    00474   if (!ki->language || !*ki->language) return 2; /* if the stream has no set language, it partially matches all */
    00475
    00476   if (!kate_ascii_strncasecmp(ki->language,language,0xffffffff)) return 1; /* perfect match */
    00477
    00478   /* if we specify a language with no subtag, it matches any subtag of the same language */
    00479   sep0=strpbrk(ki->language,"-_");
    00480   sep1=strpbrk(language,"-_");
    00481   if (!sep0 && !sep1) {
    00482     /* if none of the languages have subtags, they're different, or they'd have been picked
    00483        up by the first string comparison */
    00484     return 0; /* doesn't match */
    00485   }
    00486
    00487   if (sep0 && sep1) {
    00488     /* if both have subtags, the primary tag must be the same length */
    00489     if (sep1-language!=sep0-ki->language) return 0; /* doesn't match */
    00490   }
    00491
    00492   /* we now have primary tags to compare (with or without secondary tags), of the same length */
    00493   bytes=sep0?sep0-ki->language:sep1-language;
    00494
    00495   if (!kate_ascii_strncasecmp(ki->language,language,bytes)) return 2; /* partial match */
    00496
    00497   return 0; /* doesn't match */
    00498 }
    00499
    00508 int kate_info_remove_markup(kate_info *ki,int flag)
    00509 {
    00510   if (!ki) return KATE_E_INVALID_PARAMETER;
    00511   ki->remove_markup=flag;
    00512   return 0;
    00513 }
    00514
    00524 int kate_info_no_limits(kate_info *ki,int flag)
    00525 {
    00526   if (!ki) return KATE_E_INVALID_PARAMETER;
    00527   ki->no_limits=flag;
    00528   return 0;
    00529 }
    00530
    00539 int kate_info_clear(kate_info *ki)
    00540 {
    00541   size_t n,l;
    00542
    00543   if (!ki) return KATE_E_INVALID_PARAMETER;
    00544
    00545   if (ki->bitmaps) {
    00546     for (n=0;n<ki->nbitmaps;++n) {
    00547       kate_free(ki->bitmaps[n]->pixels);
    00548       kate_free(ki->bitmaps[n]);
    00549     }
    00550     kate_free(ki->bitmaps);
    00551   }
    00552   if (ki->palettes) {
    00553     for (n=0;n<ki->npalettes;++n) {
    00554       kate_free(ki->palettes[n]->colors);
    00555       kate_free(ki->palettes[n]);
    00556     }
    00557     kate_free(ki->palettes);
    00558   }
    00559   if (ki->motions) {
    00560     kate_motion_destroy(ki,ki->motions,NULL,ki->nmotions,1);
    00561   }
    00562   if (ki->curves) {
    00563     for (n=0;n<ki->ncurves;++n) {
    00564       kate_free(ki->curves[n]->pts);
    00565       kate_free(ki->curves[n]);
    00566     }
    00567     kate_free(ki->curves);
    00568   }
    00569   if (ki->regions) {
    00570     for (n=0;n<ki->nregions;++n) kate_free(ki->regions[n]);
    00571     kate_free(ki->regions);
    00572   }
    00573   if (ki->styles) {
    00574     for (n=0;n<ki->nstyles;++n) {
    00575       kate_style *ks=ki->styles[n];
    00576       if (ks->font) kate_free(ks->font);
    00577       kate_free(ks);
    00578     }
    00579     kate_free(ki->styles);
    00580   }
    00581   if (ki->language) kate_free(ki->language);
    00582   if (ki->category) kate_free(ki->category);
    00583   if (ki->font_mappings) {
    00584     for (n=0;n<ki->nfont_mappings;++n) {
    00585       kate_font_mapping *kfm=ki->font_mappings[n];
    00586       if (kfm->ranges) {
    00587         for (l=0;l<kfm->nranges;++l) {
    00588           int idx=kate_find_font_range(ki,kfm->ranges[l]);
    00589           if (idx<0) kate_free(kfm->ranges[l]);
    00590         }
    00591         kate_free(kfm->ranges);
    00592       }
    00593       kate_free(kfm);
    00594     }
    00595     kate_free(ki->font_mappings);
    00596   }
    00597   if (ki->font_ranges) {
    00598     for (n=0;n<ki->nfont_ranges;++n) kate_free(ki->font_ranges[n]);
    00599     kate_free(ki->font_ranges);
    00600   }
    00601
    00602   return 0;
    00603 }
    00604
    00605 static int kate_find_item(const void *item,const void **items,size_t nitems)
    00606 {
    00607   size_t n;
    00608
    00609   if (!item) return KATE_E_INVALID_PARAMETER;
    00610
    00611   if (!items) return KATE_E_NOT_FOUND; /* if nothing in the list, it may be NULL */
    00612   for (n=0;n<nitems;++n) if (item==items[n]) return n;
    00613   return KATE_E_NOT_FOUND;
    00614 }
    00615
    00616 int kate_find_region(const kate_info *ki,const kate_region *kr)
    00617 {
    00618   return kate_find_item(kr,(const void**)ki->regions,ki->nregions);
    00619 }
    00620
    00621 int kate_find_style(const kate_info *ki,const kate_style *ks)
    00622 {
    00623   return kate_find_item(ks,(const void**)ki->styles,ki->nstyles);
    00624 }
    00625
    00626 int kate_find_curve(const kate_info *ki,const kate_curve *kc)
    00627 {
    00628   return kate_find_item(kc,(const void**)ki->curves,ki->ncurves);
    00629 }
    00630
    00631 int kate_find_motion(const kate_info *ki,const kate_motion *km)
    00632 {
    00633   return kate_find_item(km,(const void**)ki->motions,ki->nmotions);
    00634 }
    00635
    00636 int kate_find_palette(const kate_info *ki,const kate_palette *kp)
    00637 {
    00638   return kate_find_item(kp,(const void**)ki->palettes,ki->npalettes);
    00639 }
    00640
    00641 int kate_find_bitmap(const kate_info *ki,const kate_bitmap *kb)
    00642 {
    00643   return kate_find_item(kb,(const void**)ki->bitmaps,ki->nbitmaps);
    00644 }
    00645
    00646 int kate_find_font_range(const kate_info *ki,const kate_font_range *kfr)
    00647 {
    00648   return kate_find_item(kfr,(const void**)ki->font_ranges,ki->nfont_ranges);
    00649 }
    00650
    00651 int kate_find_font_mapping(const kate_info *ki,const kate_font_mapping *kfm)
    00652 {
    00653   return kate_find_item(kfm,(const void**)ki->font_mappings,ki->nfont_mappings);
    00654 }
    00655