Ejemplo n.º 1
0
void BLT_lang_set(const char *str)
{
#ifdef WITH_INTERNATIONAL
	int ulang = ULANGUAGE;
	const char *short_locale = str ? str : LOCALE(ulang);
	const char *short_locale_utf8 = NULL;

	if ((U.transopts & USER_DOTRANSLATE) == 0)
		return;

	/* We want to avoid locales like '.UTF-8'! */
	if (short_locale[0]) {
		/* Hurrey! encoding needs to be placed *before* variant! */
		char *variant = strchr(short_locale, '@');
		if (variant) {
			char *locale = BLI_strdupn(short_locale, variant - short_locale);
			short_locale_utf8 = BLI_sprintfN("%s.UTF-8%s", locale, variant);
			MEM_freeN(locale);
		}
		else {
			short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale);
		}
		bl_locale_set(short_locale_utf8);
		MEM_freeN((void *)short_locale_utf8);
	}
	else {
		bl_locale_set(short_locale);
	}
#else
	(void)str;
#endif
	blt_lang_check_ime_supported();
}
Ejemplo n.º 2
0
/* Get locale's elements (if relevant pointer is not NULL and element actually exists, e.g. if there is no variant,
 * *variant and *language_variant will always be NULL).
 * Non-null elements are always MEM_mallocN'ed, it's the caller's responsibility to free them.
 * NOTE: Keep that one always available, you never know, may become useful even in no-WITH_INTERNATIONAL context...
 */
void BLT_lang_locale_explode(
        const char *locale, char **language, char **country, char **variant,
        char **language_country, char **language_variant)
{
	char *m1, *m2, *_t = NULL;

	m1 = strchr(locale, '_');
	m2 = strchr(locale, '@');

	if (language || language_variant) {
		if (m1 || m2) {
			_t = m1 ? BLI_strdupn(locale, m1 - locale) : BLI_strdupn(locale, m2 - locale);
			if (language)
				*language = _t;
		}
		else if (language) {
			*language = BLI_strdup(locale);
		}
	}
	if (country) {
		if (m1)
			*country = m2 ? BLI_strdupn(m1 + 1, m2 - (m1 + 1)) : BLI_strdup(m1 + 1);
		else
			*country = NULL;
	}
	if (variant) {
		if (m2)
			*variant = BLI_strdup(m2 + 1);
		else
			*variant = NULL;
	}
	if (language_country) {
		if (m1)
			*language_country = m2 ? BLI_strdupn(locale, m2 - locale) : BLI_strdup(locale);
		else
			*language_country = NULL;
	}
	if (language_variant) {
		if (m2)
			*language_variant = m1 ? BLI_strdupcat(_t, m2) : BLI_strdup(locale);
		else
			*language_variant = NULL;
	}
	if (_t && !language) {
		MEM_freeN(_t);
	}
}
Ejemplo n.º 3
0
/* Makes a copy of the text within the "" that appear after some text 'blahblah'
 * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples"
 * 
 * 	- str: is the entire string to chop
 *	- prefix: is the part of the string to leave out 
 *
 * Assume that the strings returned must be freed afterwards, and that the inputs will contain 
 * data we want...
 */
char *BLI_getQuotedStr (const char *str, const char *prefix)
{
	int prefixLen = strlen(prefix);
	char *startMatch, *endMatch;
	
	/* get the starting point (i.e. where prefix starts, and add prefixLen+1 to it to get be after the first " */
	startMatch= strstr(str, prefix) + prefixLen + 1;
	
	/* get the end point (i.e. where the next occurance of " is after the starting point) */
	endMatch= strchr(startMatch, '"'); // "  NOTE: this comment here is just so that my text editor still shows the functions ok...
	
	/* return the slice indicated */
	return BLI_strdupn(startMatch, (int)(endMatch-startMatch));
}
Ejemplo n.º 4
0
/* Get (or add relevant data to be able to do so) F-Curve from the driver stack, 
 * for the given Animation Data block. This assumes that all the destinations are valid.
 *	
 *	- add:	0 - don't add anything if not found, 
 *			1 - add new Driver FCurve, 
 *			-1 - add new Driver FCurve without driver stuff (for pasting)
 */
FCurve *verify_driver_fcurve (ID *id, const char rna_path[], const int array_index, short add)
{
	AnimData *adt;
	FCurve *fcu;
	
	/* sanity checks */
	if ELEM(NULL, id, rna_path)
		return NULL;
	
	/* init animdata if none available yet */
	adt= BKE_animdata_from_id(id);
	if ((adt == NULL) && (add))
		adt= BKE_id_add_animdata(id);
	if (adt == NULL) { 
		/* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
		return NULL;
	}
		
	/* try to find f-curve matching for this setting 
	 *	- add if not found and allowed to add one
	 *		TODO: add auto-grouping support? how this works will need to be resolved
	 */
	fcu= list_find_fcurve(&adt->drivers, rna_path, array_index);
	
	if ((fcu == NULL) && (add)) {
		/* use default settings to make a F-Curve */
		fcu= MEM_callocN(sizeof(FCurve), "FCurve");
		
		fcu->flag = (FCURVE_VISIBLE|FCURVE_SELECTED);
		
		/* store path - make copy, and store that */
		fcu->rna_path= BLI_strdupn(rna_path, strlen(rna_path));
		fcu->array_index= array_index;
		
		/* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */
		if (add > 0) {
			/* add some new driver data */
			fcu->driver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
			
			/* add simple generator modifier for driver so that there is some visible representation */
			add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR);
		}
		
		/* just add F-Curve to end of driver list */
		BLI_addtail(&adt->drivers, fcu);
	}
	
	/* return the F-Curve */
	return fcu;
}
Ejemplo n.º 5
0
/**
 * Reads the contents of a text file and returns the lines in a linked list.
 */
LinkNode *BLI_file_read_as_lines(const char *name)
{
	FILE *fp = BLI_fopen(name, "r");
	LinkNodePair lines = {NULL, NULL};
	char *buf;
	size_t size;

	if (!fp) return NULL;
		
	fseek(fp, 0, SEEK_END);
	size = (size_t)ftell(fp);
	fseek(fp, 0, SEEK_SET);

	if (UNLIKELY(size == (size_t)-1)) {
		fclose(fp);
		return NULL;
	}

	buf = MEM_mallocN(size, "file_as_lines");
	if (buf) {
		size_t i, last = 0;
		
		/*
		 * size = because on win32 reading
		 * all the bytes in the file will return
		 * less bytes because of crnl changes.
		 */
		size = fread(buf, 1, size, fp);
		for (i = 0; i <= size; i++) {
			if (i == size || buf[i] == '\n') {
				char *line = BLI_strdupn(&buf[last], i - last);

				BLI_linklist_append(&lines, line);
				/* faster to build singly-linked list in reverse order */
				/* alternatively, could process buffer in reverse order so
				 * list ends up right way round to start with */
				last = i + 1;
			}
		}
		
		MEM_freeN(buf);
	}
	
	fclose(fp);

	return lines.list;
}
Ejemplo n.º 6
0
/**
 * Reads the contents of a text file and returns the lines in a linked list.
 */
LinkNode *BLI_file_read_as_lines(const char *name)
{
	FILE *fp = BLI_fopen(name, "r");
	LinkNodePair lines = {NULL, NULL};
	char *buf;
	size_t size;

	if (!fp) return NULL;

	fseek(fp, 0, SEEK_END);
	size = (size_t)ftell(fp);
	fseek(fp, 0, SEEK_SET);

	if (UNLIKELY(size == (size_t)-1)) {
		fclose(fp);
		return NULL;
	}

	buf = MEM_mallocN(size, "file_as_lines");
	if (buf) {
		size_t i, last = 0;

		/*
		 * size = because on win32 reading
		 * all the bytes in the file will return
		 * less bytes because of `CRNL` changes.
		 */
		size = fread(buf, 1, size, fp);
		for (i = 0; i <= size; i++) {
			if (i == size || buf[i] == '\n') {
				char *line = BLI_strdupn(&buf[last], i - last);
				BLI_linklist_append(&lines, line);
				last = i + 1;
			}
		}

		MEM_freeN(buf);
	}

	fclose(fp);

	return lines.list;
}
Ejemplo n.º 7
0
static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from)
{
	ConsoleLine *ci = MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add");
	
	if (from) {
		BLI_assert(strlen(from->line) == from->len);
		ci->line = BLI_strdupn(from->line, from->len);
		ci->len = ci->len_alloc = from->len;
		ci->cursor = from->cursor;
		ci->type = from->type;
	}
	else {
		ci->line = MEM_callocN(64, "console-in-line");
		ci->len_alloc = 64;
		ci->len = 0;
	}
	
	BLI_addtail(lb, ci);
	return ci;
}
Ejemplo n.º 8
0
LinkNode *BLI_read_file_as_lines(const char *name)
{
	FILE *fp= fopen(name, "r");
	LinkNode *lines= NULL;
	char *buf;
	int size;

	if (!fp) return NULL;
		
	fseek(fp, 0, SEEK_END);
	size= ftell(fp);
	fseek(fp, 0, SEEK_SET);

	buf= MEM_mallocN(size, "file_as_lines");
	if (buf) {
		int i, last= 0;
		
			/* 
			 * size = because on win32 reading
			 * all the bytes in the file will return
			 * less bytes because of crnl changes.
			 */
		size= fread(buf, 1, size, fp);
		for (i=0; i<=size; i++) {
			if (i==size || buf[i]=='\n') {
				char *line= BLI_strdupn(&buf[last], i-last);

				BLI_linklist_prepend(&lines, line);
				last= i+1;
			}
		}
		
		MEM_freeN(buf);
	}
	
	fclose(fp);
	
	BLI_linklist_reverse(&lines);
	return lines;
}
Ejemplo n.º 9
0
/**
 * Duplicates the cstring \a str into a newly mallocN'd
 * string and returns it.
 *
 * \param str The string to be duplicated
 * \retval Returns the duplicated string
 */
char *BLI_strdup(const char *str)
{
	return BLI_strdupn(str, strlen(str));
}
Ejemplo n.º 10
0
static void fill_locales(void)
{
	const char * const languages_path = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale");
	char languages[FILE_MAX];
	LinkNode *lines = NULL, *line;
	char *str;
	int idx = 0;

	free_locales();

	BLI_join_dirfile(languages, FILE_MAX, languages_path, "languages");
	line = lines = BLI_file_read_as_lines(languages);

	/* This whole "parsing" code is a bit weak, in that it expects strictly formatted input file...
	 * Should not be a problem, though, as this file is script-generated! */

	/* First loop to find highest locale ID */
	while (line) {
		int t;
		str = (char *)line->link;
		if (str[0] == '#' || str[0] == '\0') {
			line = line->next;
			continue; /* Comment or void... */
		}
		t = atoi(str);
		if (t >= num_locales)
			num_locales = t + 1;
		num_locales_menu++;
		line = line->next;
	}
	num_locales_menu++; /* The "closing" void item... */

	/* And now, build locales and locale_menu! */
	locales_menu = MEM_callocN(num_locales_menu * sizeof(EnumPropertyItem), __func__);
	line = lines;
	/* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */
	if (num_locales > 0) {
		locales = MEM_callocN(num_locales * sizeof(char *), __func__);
		while (line) {
			int id;
			char *loc, *sep1, *sep2, *sep3;

			str = (char *)line->link;
			if (str[0] == '#' || str[0] == '\0') {
				line = line->next;
				continue;
			}

			id = atoi(str);
			sep1 = strchr(str, ':');
			if (sep1) {
				sep1++;
				sep2 = strchr(sep1, ':');
				if (sep2) {
					locales_menu[idx].value = id;
					locales_menu[idx].icon = 0;
					locales_menu[idx].name = BLI_strdupn(sep1, sep2 - sep1);

					sep2++;
					sep3 = strchr(sep2, ':');

					if (sep3) {
						locales_menu[idx].identifier = loc = BLI_strdupn(sep2, sep3 - sep2);
					}
					else {
						locales_menu[idx].identifier = loc = BLI_strdup(sep2);
					}

					if (id == 0) {
						/* The DEFAULT item... */
						if (BLI_strnlen(loc, 2)) {
							locales[id] = locales_menu[idx].description = BLI_strdup("");
						}
						/* Menu "label", not to be stored in locales! */
						else {
							locales_menu[idx].description = BLI_strdup("");
						}
					}
					else {
						locales[id] = locales_menu[idx].description = BLI_strdup(loc);
					}
					idx++;
				}
			}

			line = line->next;
		}
	}

	/* Add closing item to menu! */
	locales_menu[idx].identifier = NULL;
	locales_menu[idx].value = locales_menu[idx].icon = 0;
	locales_menu[idx].name = locales_menu[idx].description = "";

	BLI_file_free_lines(lines);
}
Ejemplo n.º 11
0
/* Get (or add relevant data to be able to do so) F-Curve from the driver stack, 
 * for the given Animation Data block. This assumes that all the destinations are valid.
 *	
 *	- add:	0 - don't add anything if not found, 
 *			1 - add new Driver FCurve (with keyframes for visual tweaking),
 *			2 - add new Driver FCurve (with generator, for script backwards compatibility)
 *			-1 - add new Driver FCurve without driver stuff (for pasting)
 */
FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_index, short add)
{
	AnimData *adt;
	FCurve *fcu;
	
	/* sanity checks */
	if (ELEM(NULL, id, rna_path))
		return NULL;
	
	/* init animdata if none available yet */
	adt = BKE_animdata_from_id(id);
	if ((adt == NULL) && (add))
		adt = BKE_id_add_animdata(id);
	if (adt == NULL) {
		/* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
		return NULL;
	}
		
	/* try to find f-curve matching for this setting 
	 *	- add if not found and allowed to add one
	 *		TODO: add auto-grouping support? how this works will need to be resolved
	 */
	fcu = list_find_fcurve(&adt->drivers, rna_path, array_index);
	
	if ((fcu == NULL) && (add)) {
		/* use default settings to make a F-Curve */
		fcu = MEM_callocN(sizeof(FCurve), "FCurve");
		
		fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
		
		/* store path - make copy, and store that */
		fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
		fcu->array_index = array_index;
		
		/* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */
		if (add > 0) {
			BezTriple *bezt;
			size_t i;
			
			/* add some new driver data */
			fcu->driver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
			fcu->driver->flag |= DRIVER_FLAG_SHOWDEBUG;
			
			/* F-Modifier or Keyframes? */
			// FIXME: replace these magic numbers with defines
			if (add == 2) {
				/* Python API Backwards compatibility hack:
				 * Create FModifier so that old scripts won't break
				 * for now before 2.7 series -- (September 4, 2013)
				 */
				add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR);
			}
			else {
				/* add 2 keyframes so that user has something to work with 
				 * - These are configured to 0,0 and 1,1 to give a 1-1 mapping
				 *   which can be easily tweaked from there.
				 */
				insert_vert_fcurve(fcu, 0.0f, 0.0f, INSERTKEY_FAST);
				insert_vert_fcurve(fcu, 1.0f, 1.0f, INSERTKEY_FAST);
				
				/* configure this curve to extrapolate */
				for (i = 0, bezt = fcu->bezt;  (i < fcu->totvert) && bezt;  i++, bezt++) {
					bezt->h1 = bezt->h2 = HD_VECT;
				}
				
				fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
				calchandles_fcurve(fcu);
			}
		}
		
		/* just add F-Curve to end of driver list */
		BLI_addtail(&adt->drivers, fcu);
	}
	
	/* return the F-Curve */
	return fcu;
}
Ejemplo n.º 12
0
static GHash *text_autocomplete_build(Text *text)
{
	GHash *gh;
	int seek_len = 0;
	const char *seek;
	texttool_text_clear();

	texttool_text_set_active(text);

	/* first get the word we're at */
	{
		const int i = text_find_identifier_start(text->curl->line, text->curc);
		seek_len = text->curc - i;
		seek = text->curl->line + i;

		// BLI_strncpy(seek, seek_ptr, seek_len);
	}

	/* now walk over entire doc and suggest words */
	{
		TextLine *linep;

		gh = BLI_ghash_str_new(__func__);

		for (linep = text->lines.first; linep; linep = linep->next) {
			size_t i_start = 0;
			size_t i_end = 0;
			size_t i_pos = 0;

			while (i_start < linep->len) {
				/* seek identifier beginning */
				i_pos = i_start;
				while ((i_start < linep->len) &&
				       (!text_check_identifier_nodigit_unicode(BLI_str_utf8_as_unicode_and_size_safe(&linep->line[i_start], &i_pos))))
				{
					i_start = i_pos;
				}
				i_pos = i_end = i_start;
				while ((i_end < linep->len) &&
				       (text_check_identifier_unicode(BLI_str_utf8_as_unicode_and_size_safe(&linep->line[i_end], &i_pos))))
				{
					i_end = i_pos;
				}

				if ((i_start != i_end) &&
				    /* check we're at the beginning of a line or that the previous char is not an identifier
				     * this prevents digits from being added */
				    ((i_start < 1) || !text_check_identifier_unicode(BLI_str_utf8_as_unicode(&linep->line[i_start - 1]))))
				{
					char *str_sub = &linep->line[i_start];
					const int choice_len = i_end - i_start;

					if ((choice_len > seek_len) &&
					    (seek_len == 0 || STREQLEN(seek, str_sub, seek_len)) &&
					    (seek != str_sub))
					{
						// printf("Adding: %s\n", s);
						char str_sub_last = str_sub[choice_len];
						str_sub[choice_len] = '\0';
						if (!BLI_ghash_lookup(gh, str_sub)) {
							char *str_dup = BLI_strdupn(str_sub, choice_len);
							BLI_ghash_insert(gh, str_dup, str_dup);  /* A 'set' would make more sense here */
						}
						str_sub[choice_len] = str_sub_last;
					}
				}
				if (i_end != i_start) {
					i_start = i_end;
				}
				else {
					/* highly unlikely, but prevent eternal loop */
					i_start++;
				}
			}
		}

		{
			GHashIterator gh_iter;

			/* get the formatter for highlighting */
			TextFormatType *tft;
			tft = ED_text_format_get(text);

			GHASH_ITER (gh_iter, gh) {
				const char *s = BLI_ghashIterator_getValue(&gh_iter);
				texttool_suggest_add(s, tft->format_identifier(s));
			}
		}
	}

	texttool_suggest_prefix(seek, seek_len);

	return gh;
}
Ejemplo n.º 13
0
static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int flags)
{
	JSAMPARRAY row_pointer;
	JSAMPLE *buffer = NULL;
	int row_stride;
	int x, y, depth, r, g, b, k;
	struct ImBuf *ibuf = NULL;
	uchar *rect;
	jpeg_saved_marker_ptr marker;
	char *str, *key, *value;

	/* install own app1 handler */
	ibuf_quality = jpeg_default_quality;
	jpeg_set_marker_processor(cinfo, 0xe1, handle_app1);
	cinfo->dct_method = JDCT_FLOAT;
	jpeg_save_markers(cinfo, JPEG_COM, 0xffff);

	if (jpeg_read_header(cinfo, false) == JPEG_HEADER_OK) {
		x = cinfo->image_width;
		y = cinfo->image_height;
		depth = cinfo->num_components;

		if (cinfo->jpeg_color_space == JCS_YCCK) cinfo->out_color_space = JCS_CMYK;

		jpeg_start_decompress(cinfo);

		if (flags & IB_test) {
			jpeg_abort_decompress(cinfo);
			ibuf = IMB_allocImBuf(x, y, 8 * depth, 0);
		}
		else if ((ibuf = IMB_allocImBuf(x, y, 8 * depth, IB_rect)) == NULL) {
			jpeg_abort_decompress(cinfo);
		}
		else {
			row_stride = cinfo->output_width * depth;

			row_pointer = (*cinfo->mem->alloc_sarray)((j_common_ptr) cinfo, JPOOL_IMAGE, row_stride, 1);

			for (y = ibuf->y - 1; y >= 0; y--) {
				jpeg_read_scanlines(cinfo, row_pointer, 1);
				rect = (uchar *) (ibuf->rect + y * ibuf->x);
				buffer = row_pointer[0];

				switch (depth) {
					case 1:
						for (x = ibuf->x; x > 0; x--) {
							rect[3] = 255;
							rect[0] = rect[1] = rect[2] = *buffer++;
							rect += 4;
						}
						break;
					case 3:
						for (x = ibuf->x; x > 0; x--) {
							rect[3] = 255;
							rect[0] = *buffer++;
							rect[1] = *buffer++;
							rect[2] = *buffer++;
							rect += 4;
						}
						break;
					case 4:
						for (x = ibuf->x; x > 0; x--) {
							r = *buffer++;
							g = *buffer++;
							b = *buffer++;
							k = *buffer++;

							r = (r * k) / 255;
							g = (g * k) / 255;
							b = (b * k) / 255;

							rect[3] = 255;
							rect[2] = b;
							rect[1] = g;
							rect[0] = r;
							rect += 4;
						}
						break;
				}
			}

			marker = cinfo->marker_list;
			while (marker) {
				if (marker->marker != JPEG_COM)
					goto next_stamp_marker;

				/*
				 * JPEG marker strings are not null-terminated,
				 * create a null-terminated copy before going further
				 */
				str = BLI_strdupn((char *)marker->data, marker->data_length);

				/*
				 * Because JPEG format don't support the
				 * pair "key/value" like PNG, we store the
				 * stampinfo in a single "encode" string:
				 * "Blender:key:value"
				 *
				 * That is why we need split it to the
				 * common key/value here.
				 */
				if (!STREQLEN(str, "Blender", 7)) {
					/*
					 * Maybe the file have text that
					 * we don't know "what it's", in that
					 * case we keep the text (with a
					 * key "None").
					 * This is only for don't "lose"
					 * the information when we write
					 * it back to disk.
					 */
					IMB_metadata_ensure(&ibuf->metadata);
					IMB_metadata_set_field(ibuf->metadata, "None", str);
					ibuf->flags |= IB_metadata;
					MEM_freeN(str);
					goto next_stamp_marker;
				}

				key = strchr(str, ':');
				/*
				 * A little paranoid, but the file maybe
				 * is broken... and a "extra" check is better
				 * then segfault ;)
				 */
				if (!key) {
					MEM_freeN(str);
					goto next_stamp_marker;
				}

				key++;
				value = strchr(key, ':');
				if (!value) {
					MEM_freeN(str);
					goto next_stamp_marker;
				}

				*value = '\0'; /* need finish the key string */
				value++;
				IMB_metadata_ensure(&ibuf->metadata);
				IMB_metadata_set_field(ibuf->metadata, key, value);
				ibuf->flags |= IB_metadata;
				MEM_freeN(str);
next_stamp_marker:
				marker = marker->next;
			}

			jpeg_finish_decompress(cinfo);
		}

		jpeg_destroy((j_common_ptr) cinfo);
		if (ibuf) {
			ibuf->ftype = IMB_FTYPE_JPG;
			ibuf->foptions.quality = MIN2(ibuf_quality, 100);
		}
	}

	return(ibuf);
}