void bidi_finish(void) { bidi_cmd_t *tmp; while(bidi_command_list) { tmp=bidi_command_list; bidi_command_list=bidi_command_list->next; utl_free(tmp->name); utl_free(tmp); } if(bidi_mode != MODE_BIDIOFF) { fprintf(stderr,"Warning: No %%BIDIOFF Tag at the end of the file\n"); } }
void *utl_realloc(void *ptr, size_t size, char *file, int line) { utl_mem_t *p; if (size == 0) { logInfo("realloc %p -> [0] (%u %s %d)",ptr,allocated, file, line); utl_free(ptr,file,line); } else { switch (utl_check(ptr,file,line)) { case utlMemNull : logInfo("realloc NULL (%u %s %d)",allocated, file, line); return utl_malloc(size,file,line); case utlMemValid : p = utl_mem(ptr); p = realloc(p,sizeof(utl_mem_t) + size); if (p == NULL) { logError("Out of Memory (%u %s %d)",allocated, file, line); return NULL; } allocated -= p->size; allocated += size; logInfo("realloc %p [%d] -> %p [%d] (%u %s %d)",ptr, p->size, p->data, size, allocated, file, line); p->size = size; memcpy(p->chk,BEG_CHK,4); memcpy(p->data+p->size,END_CHK,4); ptr = p->data; break; } } return ptr; }
void _SafeFree (void* freeThis) { if (freeThis != NULL) { utl_free (freeThis); } }
static void get_bidi_levels(FriBidiChar *in,int length,int is_rtl,FriBidiLevel *embed) { FriBidiCharType *types = utl_malloc(sizeof(FriBidiCharType)*length); FriBidiParType direction = is_rtl ? FRIBIDI_PAR_RTL : FRIBIDI_PAR_LTR; fribidi_get_bidi_types(in,length,types); fribidi_get_par_embedding_levels(types,length,&direction,embed); utl_free(types); }
/* The function that parses line and adds required \R \L tags */ void bidi_add_tags(FriBidiChar *in,FriBidiChar *out,int limit, int is_heb,int replace_minus) { int len,new_len,level,new_level,brakets; int i,size; int is_number_env=0; const char *tag; char *is_command; len=bidi_strlen(in); is_command=(char*)utl_malloc(len); bidi_tag_tolerant_fribidi_l2v(in,len,is_heb,bidi_embed,is_command); level=bidi_basic_level(is_heb); new_len=0; out[0]=0; brakets=0; for(i=0,new_len=0;i<len;i++){ new_level=bidi_embed[i]; if(new_level>level) { /* LTR Direction according to odd/even value of level */ is_number_env=FALSE; if((new_level & 1) == 0) { if(bidi_only_number(bidi_embed+i,in+i)){ tag=TAG_LTR_NUM; is_number_env=TRUE; } else { tag=TAG_LTR; } } else { tag=TAG_RTL; } brakets++; bidi_add_str_c(out,&new_len,limit,tag); } else if(new_level<level) { bidi_add_str_c(out,&new_len,limit,TAG_CLOSE); brakets--; } if( (new_level & 1)!=0 && !is_command[i] && (tag=bidi_mirror(in+i,&size,replace_minus))!=NULL) { /* Replace charrecter with its mirror only in case * we are in RTL direction */ /* Note this can be a sequence like "\{" */ bidi_add_str_c(out,&new_len,limit,tag); i+=size-1; } else if( (new_level & 1)!=1 && is_number_env && replace_minus && !is_command[i] && (tag=bidi_one_mirror(in+i,&size,bidi_hack_list))!=NULL) { /* Replace "--/---" with a tag "\tex{en|em}dash" only in LTR * direction only if this is nubmers environment */ bidi_add_str_c(out,&new_len,limit,tag); i+=size-1; } else { bidi_add_char_u(out,&new_len,limit,in[i]); } level=new_level; } /* Fill all missed brakets */ while(brakets){ bidi_add_str_c(out,&new_len,limit,TAG_CLOSE); brakets--; } utl_free(is_command); }
/* This function marks embedding levels at for text "in", * it ignores different tags */ void bidi_tag_tolerant_fribidi_l2v( FriBidiChar *in,int len, int is_heb, FriBidiLevel *embed, char *is_command) { int in_pos,out_pos,cmd_len,i; FriBidiChar *in_tmp; FriBidiLevel *embed_tmp,fill_level; FriBidiCharType direction; if(is_heb) direction = FRIBIDI_TYPE_RTL; else direction = FRIBIDI_TYPE_LTR; in_tmp=(FriBidiChar*)utl_malloc(sizeof(FriBidiChar)*(len+1)); embed_tmp=(FriBidiLevel*)utl_malloc(sizeof(FriBidiLevel)*len); /********************************************** * This is main parser that marks commands * * across the text i.e. marks non text * **********************************************/ bidi_mark_commands(in,len,is_command,is_heb); /**********************************************/ /* Copy all the data without tags for fribidi */ /**********************************************/ in_pos=0; out_pos=0; while(in_pos<len) { if(is_command[in_pos]){ in_pos++; continue; } /* Copy to buffer */ in_tmp[out_pos]=in[in_pos]; out_pos++; in_pos++; } /*************** * RUN FRIBIDI * ***************/ /* Note - you must take the new size for firibidi */ fribidi_log2vis_get_embedding_levels(in_tmp,out_pos,&direction,embed_tmp); /**************************************************** * Return the tags and fill missing embedding level * ****************************************************/ in_pos=0; out_pos=0; while(in_pos<len) { if(is_command[in_pos]){ /* Find the length of the part that * has a command/tag */ for(cmd_len=0;in_pos+cmd_len<len;cmd_len++) { if(!is_command[cmd_len+in_pos]) break; } if(in_pos == 0 || in_pos + cmd_len == len){ /* When we on start/end assume basic direction */ fill_level = bidi_basic_level(is_heb); } else { /* Fill with minimum on both sides */ fill_level = min(embed_tmp[out_pos-1],embed_tmp[out_pos]); } for(i=0;i<cmd_len;i++){ embed[in_pos]=fill_level; in_pos++; } continue; } /* Retrieve embedding */ embed[in_pos]=embed_tmp[out_pos]; out_pos++; in_pos++; } /* Not forget to free */ utl_free(embed_tmp); utl_free(in_tmp); }
/* This function parses the text "in" in marks places that * should be ignored by fribidi in "is_command" as true */ void bidi_mark_commands(FriBidiChar *in,int len,char *is_command,int is_heb) { char *parthness_stack; int stack_size=0; int cmd_len,top; int after_command_state=ST_NO; int mark,pos,symbol,i,push; /* Assumption - depth of stack can not be bigger then text length */ parthness_stack = utl_malloc(len); pos=0; while(pos<len) { top = stack_size == 0 ? EMPTY : parthness_stack[stack_size-1]; symbol=in[pos]; #ifdef DEBUG_STATE_MACHINE printf("pos=%d sybol=%c state=%d top=%d\n", pos,(symbol < 127 ? symbol : '#'),after_command_state,top); #endif if(bidi_is_command(in+pos,&cmd_len)) { for(i=0;i<cmd_len;i++) { is_command[i+pos]=TRUE; } if(bidi_in_cmd_list(in+pos+1,cmd_len-1)) { after_command_state = ST_IGN; } else { after_command_state = ST_NORM; } pos+=cmd_len; continue; } else if((symbol=='\\' && in[pos+1]=='\\') || symbol=='$' ) { if(symbol == '$') { cmd_len=bidi_calc_equation(in+pos); } else { cmd_len = 2; } for(i=0;i<cmd_len;i++) { is_command[i+pos]=TRUE; } pos+=cmd_len; continue; } else if( symbol == '{' ) { push = bidi_state_on_left_br(top,&after_command_state); parthness_stack[stack_size++] = push; mark=TRUE; } else if(symbol == '[' && after_command_state) { push = bidi_state_on_left_sq_br(top,&after_command_state); parthness_stack[stack_size++] = push; mark=TRUE; } else if(symbol == ']' && (top == SQ_BRACKET || top == SQ_BRACKET_IGN)){ bidi_state_on_right_sq_br(top,&after_command_state); stack_size--; mark=TRUE; } else if(symbol == '}' && (BRACKET <= top && top <= CMD_BRACKET_IGN)) { bidi_state_on_right_br(top,&after_command_state); stack_size--; mark=TRUE; } else { mark = bidi_is_ignore(top); after_command_state = ST_NO; } is_command[pos++]=mark; } utl_free(parthness_stack); }