| 
									
										
										
										
											2011-10-10 09:38:02 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							| 
									
										
										
										
											2008-01-07 19:13:47 +00:00
										 |  |  |  * of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bke | 
					
						
							| 
									
										
										
										
											2011-02-27 20:40:57 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | #include <wchar.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | #include <wctype.h>
 | 
					
						
							| 
									
										
										
										
											2002-11-25 12:02:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | #include "CLG_log.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 17:33:19 +11:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | #include "BLI_path_util.h"
 | 
					
						
							|  |  |  | #include "BLI_listbase.h"
 | 
					
						
							|  |  |  | #include "BLI_ghash.h"
 | 
					
						
							|  |  |  | #include "BLI_string.h"
 | 
					
						
							|  |  |  | #include "BLI_string_utf8.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2013-08-19 10:02:18 +00:00
										 |  |  | #include "BLI_threads.h"
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | #include "BLI_vfontdata.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_packedFile_types.h"
 | 
					
						
							|  |  |  | #include "DNA_curve_types.h"
 | 
					
						
							|  |  |  | #include "DNA_vfont_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-04 04:01:27 +00:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_packedFile.h"
 | 
					
						
							|  |  |  | #include "BKE_library.h"
 | 
					
						
							|  |  |  | #include "BKE_font.h"
 | 
					
						
							|  |  |  | #include "BKE_global.h"
 | 
					
						
							|  |  |  | #include "BKE_main.h"
 | 
					
						
							|  |  |  | #include "BKE_anim.h"
 | 
					
						
							|  |  |  | #include "BKE_curve.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | static CLG_LogRef LOG = {"bke.data_transfer"}; | 
					
						
							| 
									
										
										
										
											2013-12-29 16:40:34 +06:00
										 |  |  | static ThreadRWMutex vfont_rwlock = BLI_RWLOCK_INITIALIZER; | 
					
						
							| 
									
										
										
										
											2007-12-24 18:38:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | /* The vfont code */ | 
					
						
							| 
									
										
										
										
											2012-08-03 22:12:57 +00:00
										 |  |  | void BKE_vfont_free_data(struct VFont *vfont) | 
					
						
							| 
									
										
										
										
											2012-08-03 15:03:40 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-03 22:12:57 +00:00
										 |  |  | 	if (vfont->data) { | 
					
						
							| 
									
										
										
										
											2013-12-28 17:33:19 +11:00
										 |  |  | 		if (vfont->data->characters) { | 
					
						
							|  |  |  | 			GHashIterator gh_iter; | 
					
						
							|  |  |  | 			GHASH_ITER (gh_iter, vfont->data->characters) { | 
					
						
							|  |  |  | 				VChar *che = BLI_ghashIterator_getValue(&gh_iter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				while (che->nurbsbase.first) { | 
					
						
							|  |  |  | 					Nurb *nu = che->nurbsbase.first; | 
					
						
							|  |  |  | 					if (nu->bezt) MEM_freeN(nu->bezt); | 
					
						
							|  |  |  | 					BLI_freelinkN(&che->nurbsbase, nu); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-08-03 15:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 17:33:19 +11:00
										 |  |  | 				MEM_freeN(che); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-08-03 15:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 17:33:19 +11:00
										 |  |  | 			BLI_ghash_free(vfont->data->characters, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-03 22:12:57 +00:00
										 |  |  | 		MEM_freeN(vfont->data); | 
					
						
							|  |  |  | 		vfont->data = NULL; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-08-03 15:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-21 10:39:02 +00:00
										 |  |  | 	if (vfont->temp_pf) { | 
					
						
							|  |  |  | 		freePackedFile(vfont->temp_pf);  /* NULL when the font file can't be found on disk */ | 
					
						
							|  |  |  | 		vfont->temp_pf = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-08-03 15:03:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												ID-Remap - Step one: core work (cleanup and rework of generic ID datablock handling).
This commit changes a lot of how IDs are handled internally, especially the unlinking/freeing
processes. So far, this was very fuzy, to summarize cleanly deleting or replacing a datablock
was pretty much impossible, except for a few special cases.
Also, unlinking was handled by each datatype, in a rather messy and prone-to-errors way (quite
a few ID usages were missed or wrongly handled that way).
One of the main goal of id-remap branch was to cleanup this, and fatorize ID links handling
by using library_query utils to allow generic handling of those, which is now the case
(now, generic ID links handling is only "knwon" from readfile.c and library_query.c).
This commit also adds backends to allow live replacement and deletion of datablocks in Blender
(so-called 'remapping' process, where we replace all usages of a given ID pointer by a new one,
or NULL one in case of unlinking).
This will allow nice new features, like ability to easily reload or relocate libraries, real immediate
deletion of datablocks in blender, replacement of one datablock by another, etc.
Some of those are for next commits.
A word of warning: this commit is highly risky, because it affects potentially a lot in Blender core.
Though it was tested rather deeply, being totally impossible to check all possible ID usage cases,
it's likely there are some remaining issues and bugs in new code... Please report them! ;)
Review task: D2027 (https://developer.blender.org/D2027).
Reviewed by campbellbarton, thanks a bunch.
											
										 
											2016-06-22 17:29:38 +02:00
										 |  |  | /** Free (or release) any data used by this font (does not free the font itself). */ | 
					
						
							| 
									
										
										
										
											2012-08-03 15:03:40 +00:00
										 |  |  | void BKE_vfont_free(struct VFont *vf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BKE_vfont_free_data(vf); | 
					
						
							| 
									
										
										
										
											2012-08-21 10:39:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	if (vf->packedfile) { | 
					
						
							|  |  |  | 		freePackedFile(vf->packedfile); | 
					
						
							|  |  |  | 		vf->packedfile = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
											
										 
											2017-08-07 16:39:55 +02:00
										 |  |  | void BKE_vfont_copy_data(Main *UNUSED(bmain), VFont *vfont_dst, const VFont *UNUSED(vfont_src), const int flag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* We never handle usercount here for own data. */ | 
					
						
							|  |  |  | 	const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Just to be sure, should not have any value actually after reading time. */ | 
					
						
							|  |  |  | 	vfont_dst->temp_pf = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (vfont_dst->packedfile) { | 
					
						
							|  |  |  | 		vfont_dst->packedfile = dupPackedFile(vfont_dst->packedfile); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (vfont_dst->data) { | 
					
						
							|  |  |  | 		vfont_dst->data = BLI_vfontdata_copy(vfont_dst->data, flag_subdata); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | static void *builtin_font_data = NULL; | 
					
						
							|  |  |  | static int builtin_font_size = 0; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-09 05:35:49 +00:00
										 |  |  | bool BKE_vfont_is_builtin(struct VFont *vfont) | 
					
						
							| 
									
										
										
										
											2012-08-03 22:12:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-10 06:18:03 +00:00
										 |  |  | 	return STREQ(vfont->name, FO_BUILTIN_NAME); | 
					
						
							| 
									
										
										
										
											2012-08-03 22:12:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-05 14:52:04 +00:00
										 |  |  | void BKE_vfont_builtin_register(void *mem, int size) | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	builtin_font_data = mem; | 
					
						
							|  |  |  | 	builtin_font_size = size; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PackedFile *get_builtin_packedfile(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!builtin_font_data) { | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | 		CLOG_ERROR(&LOG, "Internal error, builtin font not loaded"); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		void *mem = MEM_mallocN(builtin_font_size, "vfd_builtin"); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		memcpy(mem, builtin_font_data, builtin_font_size); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		return newPackedFileMemory(mem, builtin_font_size); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | static VFontData *vfont_get_data(VFont *vfont) | 
					
						
							| 
									
										
										
										
											2007-12-24 18:38:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-21 10:39:02 +00:00
										 |  |  | 	if (vfont == NULL) { | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* And then set the data */ | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	if (!vfont->data) { | 
					
						
							|  |  |  | 		PackedFile *pf; | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-29 17:07:38 +06:00
										 |  |  | 		BLI_rw_mutex_lock(&vfont_rwlock, THREAD_LOCK_WRITE); | 
					
						
							| 
									
										
										
										
											2013-08-19 10:02:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (vfont->data) { | 
					
						
							|  |  |  | 			/* Check data again, since it might have been already
 | 
					
						
							|  |  |  | 			 * initialized from other thread (previous check is | 
					
						
							|  |  |  | 			 * not accurate or threading, just prevents unneeded | 
					
						
							|  |  |  | 			 * lock if all the data is here for sure). | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2013-12-29 17:07:38 +06:00
										 |  |  | 			BLI_rw_mutex_unlock(&vfont_rwlock); | 
					
						
							| 
									
										
										
										
											2013-08-19 10:02:18 +00:00
										 |  |  | 			return vfont->data; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-03 22:12:57 +00:00
										 |  |  | 		if (BKE_vfont_is_builtin(vfont)) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			pf = get_builtin_packedfile(); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			if (vfont->packedfile) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				pf = vfont->packedfile; | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* We need to copy a tmp font to memory unless it is already there */ | 
					
						
							| 
									
										
										
										
											2012-08-21 10:39:02 +00:00
										 |  |  | 				if (vfont->temp_pf == NULL) { | 
					
						
							| 
									
										
										
										
											2012-08-21 10:44:10 +00:00
										 |  |  | 					vfont->temp_pf = dupPackedFile(pf); | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-06 18:40:15 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | 				pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH_FROM_GLOBAL(&vfont->id)); | 
					
						
							| 
									
										
										
										
											2012-03-06 18:40:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-21 10:39:02 +00:00
										 |  |  | 				if (vfont->temp_pf == NULL) { | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | 					vfont->temp_pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH_FROM_GLOBAL(&vfont->id)); | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			if (!pf) { | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | 				CLOG_WARN(&LOG, "Font file doesn't exist: %s", vfont->name); | 
					
						
							| 
									
										
										
										
											2004-12-03 14:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-03 15:03:40 +00:00
										 |  |  | 				/* DON'T DO THIS
 | 
					
						
							| 
									
										
										
										
											2014-01-17 17:35:03 +11:00
										 |  |  | 				 * missing file shouldn't modify path! - campbell */ | 
					
						
							| 
									
										
										
										
											2012-08-03 15:03:40 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2010-10-24 07:02:19 +00:00
										 |  |  | 				strcpy(vfont->name, FO_BUILTIN_NAME); | 
					
						
							| 
									
										
										
										
											2012-08-03 15:03:40 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				pf = get_builtin_packedfile(); | 
					
						
							| 
									
										
										
										
											2004-12-03 14:30:32 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		if (pf) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			vfont->data = BLI_vfontdata_from_freetypefont(pf); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			if (pf != vfont->packedfile) { | 
					
						
							|  |  |  | 				freePackedFile(pf); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-08-19 10:02:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-29 17:07:38 +06:00
										 |  |  | 		BLI_rw_mutex_unlock(&vfont_rwlock); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-08-19 10:02:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 	return vfont->data; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												First step to handle missing libs/datablocks when reading a file.
Idea is, instead of ignoring completely missing linked datablocks, to
create void placeholders for them.
That way, you can work on your file, save it, and find again your missing data once
lib becomes available again. Or you can edit missing lib's path (in Outliner),
save and reload the file, and you are done.
Also, Outliner now shows broken libraries (and placeholders) with a 'broken lib' icon.
Future plans are also to be able to relocate missing libs and reload them at runtime.
Code notes:
    - Placeholder ID is just a regular datablock of same type as expected linked one,
      with 'default' data, and a LIB_MISSING bitflag set.
    - To allow creation of such datablocks, creation of datablocks in BKE was split in two step:
        + Allocation of memory itself.
        + Setting of all internal data to default values.
See also the design task (T43351).
Reviewed by @campbellbarton, thanks a bunch!
Differential Revision: https://developer.blender.org/D1394
											
										 
											2015-10-20 14:44:57 +02:00
										 |  |  | /* Bad naming actually in this case... */ | 
					
						
							|  |  |  | void BKE_vfont_init(VFont *vfont) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PackedFile *pf = get_builtin_packedfile(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (pf) { | 
					
						
							|  |  |  | 		VFontData *vfd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		vfd = BLI_vfontdata_from_freetypefont(pf); | 
					
						
							|  |  |  | 		if (vfd) { | 
					
						
							|  |  |  | 			vfont->data = vfd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			BLI_strncpy(vfont->name, FO_BUILTIN_NAME, sizeof(vfont->name)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Free the packed file */ | 
					
						
							|  |  |  | 		freePackedFile(pf); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-06 19:40:15 +11:00
										 |  |  | VFont *BKE_vfont_load(Main *bmain, const char *filepath) | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char filename[FILE_MAXFILE]; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	VFont *vfont = NULL; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	PackedFile *pf; | 
					
						
							| 
									
										
										
										
											2014-02-03 18:55:59 +11:00
										 |  |  | 	bool is_builtin; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-06 19:40:15 +11:00
										 |  |  | 	if (STREQ(filepath, FO_BUILTIN_NAME)) { | 
					
						
							|  |  |  | 		BLI_strncpy(filename, filepath, sizeof(filename)); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		pf = get_builtin_packedfile(); | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 		is_builtin = true; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2015-10-06 19:40:15 +11:00
										 |  |  | 		BLI_split_file_part(filepath, filename, sizeof(filename)); | 
					
						
							| 
									
										
										
										
											2018-06-05 15:10:33 +02:00
										 |  |  | 		pf = newPackedFile(NULL, filepath, BKE_main_blendfile_path(bmain)); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 		is_builtin = false; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (pf) { | 
					
						
							|  |  |  | 		VFontData *vfd; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		vfd = BLI_vfontdata_from_freetypefont(pf); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		if (vfd) { | 
					
						
							| 
									
										
											  
											
												Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
											
										 
											2017-08-07 16:39:55 +02:00
										 |  |  | 			vfont = BKE_libblock_alloc(bmain, ID_VF, filename, 0); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			vfont->data = vfd; | 
					
						
							| 
									
										
										
										
											2010-01-11 05:10:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* if there's a font name, use it for the ID name */ | 
					
						
							| 
									
										
										
										
											2011-05-01 06:34:40 +00:00
										 |  |  | 			if (vfd->name[0] != '\0') { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				BLI_strncpy(vfont->id.name + 2, vfd->name, sizeof(vfont->id.name) - 2); | 
					
						
							| 
									
										
										
										
											2010-01-11 05:10:57 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-10-06 19:40:15 +11:00
										 |  |  | 			BLI_strncpy(vfont->name, filepath, sizeof(vfont->name)); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 			/* if autopack is on store the packedfile in de font structure */ | 
					
						
							| 
									
										
										
										
											2019-02-02 13:39:51 +11:00
										 |  |  | 			if (!is_builtin && (G.fileflags & G_FILE_AUTOPACK)) { | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				vfont->packedfile = pf; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* Do not add FO_BUILTIN_NAME to temporary listbase */ | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  | 			if (!STREQ(filename, FO_BUILTIN_NAME)) { | 
					
						
							| 
									
										
										
										
											2018-12-27 15:22:20 +01:00
										 |  |  | 				vfont->temp_pf = newPackedFile(NULL, filepath, BKE_main_blendfile_path(bmain)); | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* Free the packed file */ | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		if (!vfont || vfont->packedfile != pf) { | 
					
						
							|  |  |  | 			freePackedFile(pf); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	return vfont; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-06 19:40:15 +11:00
										 |  |  | VFont *BKE_vfont_load_exists_ex(struct Main *bmain, const char *filepath, bool *r_exists) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	VFont *vfont; | 
					
						
							|  |  |  | 	char str[FILE_MAX], strtest[FILE_MAX]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BLI_strncpy(str, filepath, sizeof(str)); | 
					
						
							| 
									
										
										
										
											2018-06-05 15:10:33 +02:00
										 |  |  | 	BLI_path_abs(str, BKE_main_blendfile_path(bmain)); | 
					
						
							| 
									
										
										
										
											2015-10-06 19:40:15 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* first search an identical filepath */ | 
					
						
							| 
									
										
										
										
											2019-03-08 09:29:17 +11:00
										 |  |  | 	for (vfont = bmain->fonts.first; vfont; vfont = vfont->id.next) { | 
					
						
							| 
									
										
										
										
											2015-10-06 19:40:15 +11:00
										 |  |  | 		BLI_strncpy(strtest, vfont->name, sizeof(vfont->name)); | 
					
						
							|  |  |  | 		BLI_path_abs(strtest, ID_BLEND_PATH(bmain, &vfont->id)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (BLI_path_cmp(strtest, str) == 0) { | 
					
						
							| 
									
										
										
										
											2015-11-09 19:47:10 +01:00
										 |  |  | 			id_us_plus(&vfont->id);  /* officially should not, it doesn't link here! */ | 
					
						
							| 
									
										
										
										
											2015-10-06 19:40:15 +11:00
										 |  |  | 			if (r_exists) | 
					
						
							|  |  |  | 				*r_exists = true; | 
					
						
							|  |  |  | 			return vfont; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (r_exists) | 
					
						
							|  |  |  | 		*r_exists = false; | 
					
						
							|  |  |  | 	return BKE_vfont_load(bmain, filepath); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | VFont *BKE_vfont_load_exists(struct Main *bmain, const char *filepath) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return BKE_vfont_load_exists_ex(bmain, filepath, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-21 16:09:08 +02:00
										 |  |  | void BKE_vfont_make_local(Main *bmain, VFont *vfont, const bool lib_local) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BKE_id_make_local_generic(bmain, &vfont->id, true, lib_local); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | static VFont *which_vfont(Curve *cu, CharInfo *info) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	switch (info->flag & (CU_CHINFO_BOLD | CU_CHINFO_ITALIC)) { | 
					
						
							| 
									
										
										
										
											2010-07-13 23:51:21 +00:00
										 |  |  | 		case CU_CHINFO_BOLD: | 
					
						
							| 
									
										
										
										
											2012-08-21 10:44:10 +00:00
										 |  |  | 			return cu->vfontb ? cu->vfontb : cu->vfont; | 
					
						
							| 
									
										
										
										
											2010-07-13 23:51:21 +00:00
										 |  |  | 		case CU_CHINFO_ITALIC: | 
					
						
							| 
									
										
										
										
											2012-08-21 10:44:10 +00:00
										 |  |  | 			return cu->vfonti ? cu->vfonti : cu->vfont; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		case (CU_CHINFO_BOLD | CU_CHINFO_ITALIC): | 
					
						
							| 
									
										
										
										
											2012-08-21 10:44:10 +00:00
										 |  |  | 			return cu->vfontbi ? cu->vfontbi : cu->vfont; | 
					
						
							| 
									
										
										
										
											2005-09-19 17:58:51 +00:00
										 |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2012-08-21 10:44:10 +00:00
										 |  |  | 			return cu->vfont; | 
					
						
							| 
									
										
										
										
											2012-08-21 10:39:02 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-05 14:52:04 +00:00
										 |  |  | VFont *BKE_vfont_builtin_get(void) | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-03 22:12:57 +00:00
										 |  |  | 	VFont *vfont; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-08 09:29:17 +11:00
										 |  |  | 	for (vfont = G_MAIN->fonts.first; vfont; vfont = vfont->id.next) { | 
					
						
							| 
									
										
										
										
											2012-08-03 22:12:57 +00:00
										 |  |  | 		if (BKE_vfont_is_builtin(vfont)) { | 
					
						
							|  |  |  | 			return vfont; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | 	return BKE_vfont_load(G_MAIN, FO_BUILTIN_NAME); | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 17:33:19 +11:00
										 |  |  | static VChar *find_vfont_char(VFontData *vfd, unsigned int character) | 
					
						
							| 
									
										
										
										
											2010-07-13 23:51:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-19 12:05:58 +10:00
										 |  |  | 	return BLI_ghash_lookup(vfd->characters, POINTER_FROM_UINT(character)); | 
					
						
							| 
									
										
										
										
											2010-07-13 23:51:21 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-01-07 20:18:11 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 23:04:47 +11:00
										 |  |  | static void build_underline(Curve *cu, ListBase *nubase, const rctf *rect, | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  |                             float yofs, float rot, int charidx, short mat_nr, | 
					
						
							|  |  |  |                             const float font_size) | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Nurb *nu2; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	nu2 = (Nurb *) MEM_callocN(sizeof(Nurb), "underline_nurb"); | 
					
						
							|  |  |  | 	nu2->resolu = cu->resolu; | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 	nu2->bezt = NULL; | 
					
						
							| 
									
										
										
										
											2008-05-26 09:50:46 +00:00
										 |  |  | 	nu2->knotsu = nu2->knotsv = NULL; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	nu2->flag = CU_2D; | 
					
						
							|  |  |  | 	nu2->charidx = charidx + 1000; | 
					
						
							|  |  |  | 	if (mat_nr > 0) nu2->mat_nr = mat_nr - 1; | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 	nu2->pntsu = 4; | 
					
						
							|  |  |  | 	nu2->pntsv = 1; | 
					
						
							|  |  |  | 	nu2->orderu = 4; | 
					
						
							|  |  |  | 	nu2->orderv = 1; | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  | 	nu2->flagu = CU_NURB_CYCLIC; | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 	bp = (BPoint *)MEM_calloc_arrayN(4, sizeof(BPoint), "underline_bp"); | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:00:53 +10:00
										 |  |  | 	copy_v4_fl4(bp[0].vec, rect->xmin, (rect->ymax + yofs), 0.0f, 1.0f); | 
					
						
							|  |  |  | 	copy_v4_fl4(bp[1].vec, rect->xmax, (rect->ymax + yofs), 0.0f, 1.0f); | 
					
						
							|  |  |  | 	copy_v4_fl4(bp[2].vec, rect->xmax, (rect->ymin + yofs), 0.0f, 1.0f); | 
					
						
							|  |  |  | 	copy_v4_fl4(bp[3].vec, rect->xmin, (rect->ymin + yofs), 0.0f, 1.0f); | 
					
						
							| 
									
										
										
										
											2013-10-22 03:31:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	nu2->bp = bp; | 
					
						
							| 
									
										
										
										
											2014-01-05 17:04:52 +06:00
										 |  |  | 	BLI_addtail(nubase, nu2); | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 20:18:11 +11:00
										 |  |  | 	if (rot != 0.0f) { | 
					
						
							|  |  |  | 		float si, co; | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		si = sinf(rot); | 
					
						
							|  |  |  | 		co = cosf(rot); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (i = nu2->pntsu; i > 0; i--) { | 
					
						
							|  |  |  | 			float *fp; | 
					
						
							|  |  |  | 			float x, y; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			fp = bp->vec; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 23:04:47 +11:00
										 |  |  | 			x = fp[0] - rect->xmin; | 
					
						
							|  |  |  | 			y = fp[1] - rect->ymin; | 
					
						
							| 
									
										
										
										
											2014-01-07 20:18:11 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 23:04:47 +11:00
										 |  |  | 			fp[0] = (+co * x + si * y) + rect->xmin; | 
					
						
							|  |  |  | 			fp[1] = (-si * x + co * y) + rect->ymin; | 
					
						
							| 
									
										
										
										
											2014-01-07 20:18:11 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			bp++; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-01-08 00:57:30 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		bp = nu2->bp; | 
					
						
							| 
									
										
										
										
											2014-01-07 20:18:11 +11:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 	mul_v2_fl(bp[0].vec, font_size); | 
					
						
							|  |  |  | 	mul_v2_fl(bp[1].vec, font_size); | 
					
						
							|  |  |  | 	mul_v2_fl(bp[2].vec, font_size); | 
					
						
							|  |  |  | 	mul_v2_fl(bp[3].vec, font_size); | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | static void buildchar(Curve *cu, ListBase *nubase, unsigned int character, CharInfo *info, | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  |                       float ofsx, float ofsy, float rot, int charidx, | 
					
						
							|  |  |  |                       const float fsize) | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	BezTriple *bezt1, *bezt2; | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 	Nurb *nu1 = NULL, *nu2 = NULL; | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 	float *fp, shear, x, si, co; | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 	VFontData *vfd = NULL; | 
					
						
							|  |  |  | 	VChar *che = NULL; | 
					
						
							| 
									
										
										
										
											2010-10-05 21:22:33 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | 	vfd = vfont_get_data(which_vfont(cu, info)); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	if (!vfd) return; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:19:11 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 	if (cu->selend < cu->selstart) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		if ((charidx >= (cu->selend)) && (charidx <= (cu->selstart - 2))) | 
					
						
							|  |  |  | 			sel = 1; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		if ((charidx >= (cu->selstart - 1)) && (charidx <= (cu->selend - 1))) | 
					
						
							|  |  |  | 			sel = 1; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-03 20:19:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-17 14:43:20 +00:00
										 |  |  | 	/* make a copy at distance ofsx, ofsy with shear */ | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	shear = cu->shear; | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 	si = sinf(rot); | 
					
						
							|  |  |  | 	co = cosf(rot); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	che = find_vfont_char(vfd, character); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 	/* Select the glyph data */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	if (che) | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 		nu1 = che->nurbsbase.first; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 	/* Create the character */ | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 	while (nu1) { | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		bezt1 = nu1->bezt; | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 		if (bezt1) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			nu2 = (Nurb *) MEM_mallocN(sizeof(Nurb), "duplichar_nurb"); | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 			if (nu2 == NULL) break; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			memcpy(nu2, nu1, sizeof(struct Nurb)); | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			nu2->resolu = cu->resolu; | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 			nu2->bp = NULL; | 
					
						
							| 
									
										
										
										
											2008-05-26 09:50:46 +00:00
										 |  |  | 			nu2->knotsu = nu2->knotsv = NULL; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			nu2->flag = CU_SMOOTH; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 			nu2->charidx = charidx; | 
					
						
							| 
									
										
										
										
											2011-10-11 23:08:17 +00:00
										 |  |  | 			if (info->mat_nr > 0) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				nu2->mat_nr = info->mat_nr - 1; | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				nu2->mat_nr = 0; | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			/* nu2->trim.first = 0; */ | 
					
						
							|  |  |  | 			/* nu2->trim.last = 0; */ | 
					
						
							|  |  |  | 			i = nu2->pntsu; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 			bezt2 = (BezTriple *)MEM_malloc_arrayN(i, sizeof(BezTriple), "duplichar_bezt2"); | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 			if (bezt2 == NULL) { | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				MEM_freeN(nu2); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			memcpy(bezt2, bezt1, i * sizeof(struct BezTriple)); | 
					
						
							|  |  |  | 			nu2->bezt = bezt2; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-28 11:21:39 +00:00
										 |  |  | 			if (shear != 0.0f) { | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				bezt2 = nu2->bezt; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				for (i = nu2->pntsu; i > 0; i--) { | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 					bezt2->vec[0][0] += shear * bezt2->vec[0][1]; | 
					
						
							|  |  |  | 					bezt2->vec[1][0] += shear * bezt2->vec[1][1]; | 
					
						
							|  |  |  | 					bezt2->vec[2][0] += shear * bezt2->vec[2][1]; | 
					
						
							|  |  |  | 					bezt2++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			if (rot != 0.0f) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				bezt2 = nu2->bezt; | 
					
						
							|  |  |  | 				for (i = nu2->pntsu; i > 0; i--) { | 
					
						
							|  |  |  | 					fp = bezt2->vec[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					x = fp[0]; | 
					
						
							|  |  |  | 					fp[0] = co * x + si * fp[1]; | 
					
						
							|  |  |  | 					fp[1] = -si * x + co * fp[1]; | 
					
						
							|  |  |  | 					x = fp[3]; | 
					
						
							|  |  |  | 					fp[3] = co * x + si * fp[4]; | 
					
						
							|  |  |  | 					fp[4] = -si * x + co * fp[4]; | 
					
						
							|  |  |  | 					x = fp[6]; | 
					
						
							|  |  |  | 					fp[6] = co * x + si * fp[7]; | 
					
						
							|  |  |  | 					fp[7] = -si * x + co * fp[7]; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					bezt2++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			bezt2 = nu2->bezt; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				const float sca = cu->smallcaps_scale; | 
					
						
							|  |  |  | 				for (i = nu2->pntsu; i > 0; i--) { | 
					
						
							|  |  |  | 					fp = bezt2->vec[0]; | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | 					fp[0] *= sca; | 
					
						
							|  |  |  | 					fp[1] *= sca; | 
					
						
							|  |  |  | 					fp[3] *= sca; | 
					
						
							|  |  |  | 					fp[4] *= sca; | 
					
						
							|  |  |  | 					fp[6] *= sca; | 
					
						
							|  |  |  | 					fp[7] *= sca; | 
					
						
							|  |  |  | 					bezt2++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			bezt2 = nu2->bezt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			for (i = nu2->pntsu; i > 0; i--) { | 
					
						
							|  |  |  | 				fp = bezt2->vec[0]; | 
					
						
							|  |  |  | 				fp[0] = (fp[0] + ofsx) * fsize; | 
					
						
							|  |  |  | 				fp[1] = (fp[1] + ofsy) * fsize; | 
					
						
							|  |  |  | 				fp[3] = (fp[3] + ofsx) * fsize; | 
					
						
							|  |  |  | 				fp[4] = (fp[4] + ofsy) * fsize; | 
					
						
							|  |  |  | 				fp[6] = (fp[6] + ofsx) * fsize; | 
					
						
							|  |  |  | 				fp[7] = (fp[7] + ofsy) * fsize; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				bezt2++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-05 17:04:52 +06:00
										 |  |  | 			BLI_addtail(nubase, nu2); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		nu1 = nu1->next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | int BKE_vfont_select_get(Object *ob, int *r_start, int *r_end) | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	Curve *cu = ob->data; | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 	EditFont *ef = cu->editfont; | 
					
						
							| 
									
										
										
										
											2014-09-10 21:08:40 +10:00
										 |  |  | 	int start, end, direction; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 	if ((ob->type != OB_FONT) || (ef == NULL)) return 0; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-10 23:01:22 +10:00
										 |  |  | 	BLI_assert(ef->len >= 0); | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 	BLI_assert(ef->selstart >= 0 && ef->selstart <= ef->len + 1); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:31:40 +10:00
										 |  |  | 	BLI_assert(ef->selend   >= 0 && ef->selend   <= ef->len + 1); | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 	BLI_assert(ef->pos      >= 0 && ef->pos      <= ef->len); | 
					
						
							| 
									
										
										
										
											2013-12-29 23:16:02 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-10 21:08:40 +10:00
										 |  |  | 	if (ef->selstart == 0) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 	if (ef->selstart <= ef->selend) { | 
					
						
							| 
									
										
										
										
											2014-09-10 21:08:40 +10:00
										 |  |  | 		start = ef->selstart - 1; | 
					
						
							|  |  |  | 		end = ef->selend - 1; | 
					
						
							|  |  |  | 		direction = 1; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2014-09-10 21:08:40 +10:00
										 |  |  | 		start = ef->selend; | 
					
						
							|  |  |  | 		end = ef->selstart - 2; | 
					
						
							|  |  |  | 		direction = -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (start == end + 1) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-09-10 21:08:40 +10:00
										 |  |  | 	else { | 
					
						
							|  |  |  | 		BLI_assert(start < end + 1); | 
					
						
							|  |  |  | 		*r_start = start; | 
					
						
							|  |  |  | 		*r_end = end; | 
					
						
							|  |  |  | 		return direction; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BKE_vfont_select_clamp(Object *ob) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Curve *cu = ob->data; | 
					
						
							|  |  |  | 	EditFont *ef = cu->editfont; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BLI_assert((ob->type == OB_FONT) && ef); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CLAMP_MAX(ef->pos,      ef->len); | 
					
						
							|  |  |  | 	CLAMP_MAX(ef->selstart, ef->len + 1); | 
					
						
							|  |  |  | 	CLAMP_MAX(ef->selend,   ef->len); | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | static float char_width(Curve *cu, VChar *che, CharInfo *info) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-24 17:27:41 +02:00
										 |  |  | 	/* The character wasn't found, probably ascii = 0, then the width shall be 0 as well */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	if (che == NULL) { | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | 		return 0.0f; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	else if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) { | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | 		return che->width * cu->smallcaps_scale; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		return che->width; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | static void textbox_scale(TextBox *tb_dst, const TextBox *tb_src, float scale) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	tb_dst->x = tb_src->x * scale; | 
					
						
							|  |  |  | 	tb_dst->y = tb_src->y * scale; | 
					
						
							|  |  |  | 	tb_dst->w = tb_src->w * scale; | 
					
						
							|  |  |  | 	tb_dst->h = tb_src->h * scale; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Used for storing per-line data for alignment & wrapping. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | struct TempLineInfo { | 
					
						
							|  |  |  | 	float x_min;      /* left margin */ | 
					
						
							|  |  |  | 	float x_max;      /* right margin */ | 
					
						
							|  |  |  | 	int   char_nr;    /* number of characters */ | 
					
						
							|  |  |  | 	int   wspace_nr;  /* number of whitespaces of line */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | typedef struct VFontToCurveIter { | 
					
						
							|  |  |  | 	int iteraction; | 
					
						
							|  |  |  | 	float scale_to_fit; | 
					
						
							|  |  |  | 	struct { | 
					
						
							|  |  |  | 		float min; | 
					
						
							|  |  |  | 		float max; | 
					
						
							|  |  |  | 	} bisect; | 
					
						
							|  |  |  | 	bool ok; | 
					
						
							|  |  |  | 	int status; | 
					
						
							|  |  |  | } VFontToCurveIter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  | 	VFONT_TO_CURVE_INIT = 0, | 
					
						
							|  |  |  | 	VFONT_TO_CURVE_BISECT, | 
					
						
							|  |  |  | 	VFONT_TO_CURVE_SCALE_ONCE, | 
					
						
							|  |  |  | 	VFONT_TO_CURVE_DONE, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define FONT_TO_CURVE_SCALE_ITERATIONS 20
 | 
					
						
							|  |  |  | #define FONT_TO_CURVE_SCALE_THRESHOLD 0.0001f
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-05 11:21:12 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Font metric values explained: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Baseline: Line where the text "rests", used as the origin vertical position for the glyphs. | 
					
						
							|  |  |  |  * Em height: Space most glyphs should fit within. | 
					
						
							|  |  |  |  * Ascent: the recommended distance above the baseline to fit most characters. | 
					
						
							|  |  |  |  * Descent: the recommended distance below the baseline to fit most characters. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * We obtain ascent and descent from the font itself (FT_Face->ascender / face->height). | 
					
						
							|  |  |  |  * And in some cases it is even the same value as FT_Face->bbox.yMax/yMin (font top and bottom respectively). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The em_height here is relative to FT_Face->bbox. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | #define ASCENT(vfd) ((vfd)->ascender * (vfd)->em_height)
 | 
					
						
							|  |  |  | #define DESCENT(vfd) ((vfd)->em_height - ASCENT(vfd))
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | static bool vfont_to_curve(Object *ob, Curve *cu, int mode, | 
					
						
							|  |  |  |                            VFontToCurveIter *iter_data, | 
					
						
							|  |  |  |                            ListBase *r_nubase, | 
					
						
							| 
									
										
										
										
											2014-01-06 01:48:25 +11:00
										 |  |  |                            const wchar_t **r_text, int *r_text_len, bool *r_text_free, | 
					
						
							|  |  |  |                            struct CharTrans **r_chartransdata) | 
					
						
							| 
									
										
										
										
											2012-05-17 23:21:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 	EditFont *ef = cu->editfont; | 
					
						
							| 
									
										
										
										
											2014-01-07 17:04:19 +11:00
										 |  |  | 	EditFontSelBox *selboxes = NULL; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 	VFont *vfont, *oldvfont; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	VFontData *vfd = NULL; | 
					
						
							| 
									
										
										
										
											2010-12-31 20:01:38 +00:00
										 |  |  | 	CharInfo *info = NULL, *custrinfo; | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 	TextBox tb_scale; | 
					
						
							|  |  |  | 	bool use_textbox; | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 	VChar *che; | 
					
						
							| 
									
										
										
										
											2012-08-03 23:44:50 +00:00
										 |  |  | 	struct CharTrans *chartransdata = NULL, *ct; | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 	struct TempLineInfo *lineinfo; | 
					
						
							|  |  |  | 	float *f, xof, yof, xtrax, linedist; | 
					
						
							| 
									
										
										
										
											2018-11-26 21:54:29 -02:00
										 |  |  | 	float twidth = 0, maxlen = 0; | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | 	int i, slen, j; | 
					
						
							|  |  |  | 	int curbox; | 
					
						
							|  |  |  | 	int selstart, selend; | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 	int cnr = 0, lnr = 0, wsnr = 0; | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 	const wchar_t *mem = NULL; | 
					
						
							| 
									
										
										
										
											2014-01-05 20:52:31 +11:00
										 |  |  | 	wchar_t ascii; | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 	bool ok = false; | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 	const float font_size = cu->fsize * iter_data->scale_to_fit; | 
					
						
							|  |  |  | 	const float xof_scale = cu->xof / font_size; | 
					
						
							|  |  |  | 	const float yof_scale = cu->yof / font_size; | 
					
						
							|  |  |  | 	int last_line = -1; | 
					
						
							|  |  |  | 	/* Length of the text disregarding \n breaks. */ | 
					
						
							|  |  |  | 	float current_line_length = 0.0f; | 
					
						
							|  |  |  | 	float longest_line_length = 0.0f; | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-10 18:13:08 -03:00
										 |  |  | 	/* Text at the beginning of the last used text-box (use for y-axis alignment).
 | 
					
						
							|  |  |  | 	 * We overallocate by one to simplify logic of getting last char. */ | 
					
						
							|  |  |  | 	int *i_textbox_array = MEM_callocN(sizeof(*i_textbox_array) * (cu->totbox + 1), "TextBox initial char index"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | #define MARGIN_X_MIN (xof_scale + tb_scale.x)
 | 
					
						
							|  |  |  | #define MARGIN_Y_MIN (yof_scale + tb_scale.y)
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 	/* remark: do calculations including the trailing '\0' of a string
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:19:11 +00:00
										 |  |  | 	 * because the cursor can be at that location */ | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 15:08:29 +01:00
										 |  |  | 	BLI_assert(ob == NULL || ob->type == OB_FONT); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 	/* Set font data */ | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	vfont = cu->vfont; | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 	if (cu->str == NULL) return ok; | 
					
						
							|  |  |  | 	if (vfont == NULL) return ok; | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | 	vfd = vfont_get_data(vfont); | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 	/* The VFont Data can not be found */ | 
					
						
							|  |  |  | 	if (!vfd) return ok; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 	if (ef) { | 
					
						
							|  |  |  | 		slen = ef->len; | 
					
						
							|  |  |  | 		mem = ef->textbuf; | 
					
						
							|  |  |  | 		custrinfo = ef->textbufinfo; | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2014-01-05 20:52:31 +11:00
										 |  |  | 		wchar_t *mem_tmp; | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 		slen = cu->len_wchar; | 
					
						
							| 
									
										
										
										
											2005-10-28 15:36:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 		/* Create unicode string */ | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 		mem_tmp = MEM_malloc_arrayN((slen + 1), sizeof(wchar_t), "convertedmem"); | 
					
						
							| 
									
										
										
										
											2018-01-15 06:57:26 +01:00
										 |  |  | 		if (!mem_tmp) { | 
					
						
							|  |  |  | 			return ok; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-05 20:52:31 +11:00
										 |  |  | 		BLI_strncpy_wchar_from_utf8(mem_tmp, cu->str, slen + 1); | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (cu->strinfo == NULL) {  /* old file */ | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 			cu->strinfo = MEM_calloc_arrayN((slen + 4), sizeof(CharInfo), "strinfo compat"); | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		custrinfo = cu->strinfo; | 
					
						
							| 
									
										
										
										
											2018-01-15 06:57:26 +01:00
										 |  |  | 		if (!custrinfo) { | 
					
						
							|  |  |  | 			return ok; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-01-05 20:52:31 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		mem = mem_tmp; | 
					
						
							| 
									
										
										
										
											2005-10-28 15:36:09 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 	if (cu->tb == NULL) | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 		cu->tb = MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), "TextBox compat"); | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 15:08:29 +01:00
										 |  |  | 	if (ef != NULL && ob != NULL) { | 
					
						
							| 
									
										
										
										
											2014-01-07 17:04:19 +11:00
										 |  |  | 		if (ef->selboxes) | 
					
						
							|  |  |  | 			MEM_freeN(ef->selboxes); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:08:28 +10:00
										 |  |  | 		if (BKE_vfont_select_get(ob, &selstart, &selend)) { | 
					
						
							|  |  |  | 			ef->selboxes_len = (selend - selstart) + 1; | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 			ef->selboxes = MEM_calloc_arrayN(ef->selboxes_len, sizeof(EditFontSelBox), "font selboxes"); | 
					
						
							| 
									
										
										
										
											2017-04-21 17:08:28 +10:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			ef->selboxes_len = 0; | 
					
						
							| 
									
										
										
										
											2014-01-07 17:04:19 +11:00
										 |  |  | 			ef->selboxes = NULL; | 
					
						
							| 
									
										
										
										
											2017-04-21 17:08:28 +10:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-01-07 17:04:19 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		selboxes = ef->selboxes; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-26 11:56:44 +00:00
										 |  |  | 	/* calc offset and rotation of each char */ | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 	ct = chartransdata = MEM_calloc_arrayN((slen + 1), sizeof(struct CharTrans), "buildtext"); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 	/* We assume the worst case: 1 character per line (is freed at end anyway) */ | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 	lineinfo = MEM_malloc_arrayN((slen * 2 + 1), sizeof(*lineinfo), "lineinfo"); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	linedist = cu->linedist; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 	curbox = 0; | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 	textbox_scale(&tb_scale, &cu->tb[curbox], 1.0f / font_size); | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 	use_textbox = (tb_scale.w != 0.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xof = MARGIN_X_MIN; | 
					
						
							|  |  |  | 	yof = MARGIN_Y_MIN; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	xtrax = 0.5f * cu->spacing - 0.5f; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	oldvfont = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 	for (i = 0; i < slen; i++) { | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 		custrinfo[i].flag &= ~(CU_CHINFO_WRAP | CU_CHINFO_SMALLCAPS_CHECK | CU_CHINFO_OVERFLOW); | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	for (i = 0; i <= slen; i++) { | 
					
						
							|  |  |  | makebreak: | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 		/* Characters in the list */ | 
					
						
							| 
									
										
										
										
											2014-01-05 20:50:15 +11:00
										 |  |  | 		info = &custrinfo[i]; | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | 		ascii = mem[i]; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		if (info->flag & CU_CHINFO_SMALLCAPS) { | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | 			ascii = towupper(ascii); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			if (mem[i] != ascii) { | 
					
						
							| 
									
										
										
										
											2010-07-13 23:51:21 +00:00
										 |  |  | 				info->flag |= CU_CHINFO_SMALLCAPS_CHECK; | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 		vfont = which_vfont(cu, info); | 
					
						
							| 
									
										
										
										
											2014-01-05 20:00:03 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		if (vfont == NULL) break; | 
					
						
							| 
									
										
										
										
											2010-07-13 23:51:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-05 20:00:03 +11:00
										 |  |  | 		if (vfont != oldvfont) { | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | 			vfd = vfont_get_data(vfont); | 
					
						
							| 
									
										
										
										
											2014-01-05 20:00:03 +11:00
										 |  |  | 			oldvfont = vfont; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* VFont Data for VFont couldn't be found */ | 
					
						
							|  |  |  | 		if (!vfd) { | 
					
						
							|  |  |  | 			MEM_freeN(chartransdata); | 
					
						
							|  |  |  | 			chartransdata = NULL; | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 			MEM_freeN(lineinfo); | 
					
						
							| 
									
										
										
										
											2014-01-05 20:00:03 +11:00
										 |  |  | 			goto finally; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 19:34:50 +11:00
										 |  |  | 		if (!ELEM(ascii, '\n', '\0')) { | 
					
						
							| 
									
										
										
										
											2013-12-29 16:40:34 +06:00
										 |  |  | 			BLI_rw_mutex_lock(&vfont_rwlock, THREAD_LOCK_READ); | 
					
						
							| 
									
										
										
										
											2013-12-28 19:04:03 +11:00
										 |  |  | 			che = find_vfont_char(vfd, ascii); | 
					
						
							| 
									
										
										
										
											2013-12-29 16:40:34 +06:00
										 |  |  | 			BLI_rw_mutex_unlock(&vfont_rwlock); | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 19:04:03 +11:00
										 |  |  | 			/*
 | 
					
						
							|  |  |  | 			 * The character wasn't in the current curve base so load it | 
					
						
							|  |  |  | 			 * But if the font is built-in then do not try loading since | 
					
						
							|  |  |  | 			 * whole font is in the memory already | 
					
						
							|  |  |  | 			 */ | 
					
						
							|  |  |  | 			if (che == NULL && BKE_vfont_is_builtin(vfont) == false) { | 
					
						
							| 
									
										
										
										
											2013-12-29 16:40:34 +06:00
										 |  |  | 				BLI_rw_mutex_lock(&vfont_rwlock, THREAD_LOCK_WRITE); | 
					
						
							|  |  |  | 				/* Check it once again, char might have been already load
 | 
					
						
							|  |  |  | 				 * between previous BLI_rw_mutex_unlock() and this BLI_rw_mutex_lock(). | 
					
						
							|  |  |  | 				 * | 
					
						
							|  |  |  | 				 * Such a check should not be a bottleneck since it wouldn't | 
					
						
							|  |  |  | 				 * happen often once all the chars are load. | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 				if ((che = find_vfont_char(vfd, ascii)) == NULL) { | 
					
						
							|  |  |  | 					che = BLI_vfontchar_from_freetypefont(vfont, ascii); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				BLI_rw_mutex_unlock(&vfont_rwlock); | 
					
						
							| 
									
										
										
										
											2013-12-28 19:04:03 +11:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-12-28 19:34:50 +11:00
										 |  |  | 		else { | 
					
						
							|  |  |  | 			che = NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | 		twidth = char_width(cu, che, info); | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 		/* Calculate positions */ | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 		if ((tb_scale.w != 0.0f) && | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 		    (ct->dobreak == 0) && | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 		    (((xof - tb_scale.x) + twidth) > xof_scale + tb_scale.w)) | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | 			//		CLOG_WARN(&LOG, "linewidth exceeded: %c%c%c...", mem[i], mem[i+1], mem[i+2]);
 | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 			for (j = i; j && (mem[j] != '\n') && (chartransdata[j].dobreak == 0); j--) { | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				bool dobreak = false; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				if (mem[j] == ' ' || mem[j] == '-') { | 
					
						
							|  |  |  | 					ct -= (i - (j - 1)); | 
					
						
							|  |  |  | 					cnr -= (i - (j - 1)); | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 					if (mem[j] == ' ') wsnr--; | 
					
						
							|  |  |  | 					if (mem[j] == '-') wsnr++; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 					i = j - 1; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 					xof = ct->xof; | 
					
						
							|  |  |  | 					ct[1].dobreak = 1; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 					custrinfo[i + 1].flag |= CU_CHINFO_WRAP; | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 					dobreak = true; | 
					
						
							| 
									
										
										
										
											2005-10-28 15:36:09 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				else if (chartransdata[j].dobreak) { | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | 					//				CLOG_WARN(&LOG, "word too long: %c%c%c...", mem[j], mem[j+1], mem[j+2]);
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 					ct->dobreak = 1; | 
					
						
							|  |  |  | 					custrinfo[i + 1].flag |= CU_CHINFO_WRAP; | 
					
						
							| 
									
										
										
										
											2005-10-28 15:36:09 +00:00
										 |  |  | 					ct -= 1; | 
					
						
							|  |  |  | 					cnr -= 1; | 
					
						
							|  |  |  | 					i--; | 
					
						
							|  |  |  | 					xof = ct->xof; | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 					dobreak = true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (dobreak) { | 
					
						
							|  |  |  | 					if (tb_scale.h == 0.0f) { | 
					
						
							|  |  |  | 						/* Note: If underlined text is truncated away, the extra space is also truncated. */ | 
					
						
							|  |  |  | 						custrinfo[i + 1].flag |= CU_CHINFO_OVERFLOW; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2005-10-28 15:36:09 +00:00
										 |  |  | 					goto makebreak; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2005-09-19 17:58:51 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 		if (ascii == '\n' || ascii == 0 || ct->dobreak) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			ct->xof = xof; | 
					
						
							|  |  |  | 			ct->yof = yof; | 
					
						
							|  |  |  | 			ct->linenr = lnr; | 
					
						
							|  |  |  | 			ct->charnr = cnr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			yof -= linedist; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 			lineinfo[lnr].x_min     = (xof - xtrax) - tb_scale.x; | 
					
						
							|  |  |  | 			lineinfo[lnr].x_max     = tb_scale.w; | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 			lineinfo[lnr].char_nr   = cnr; | 
					
						
							|  |  |  | 			lineinfo[lnr].wspace_nr = wsnr; | 
					
						
							| 
									
										
										
										
											2014-05-15 15:43:59 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 			CLAMP_MIN(maxlen, lineinfo[lnr].x_min); | 
					
						
							| 
									
										
										
										
											2014-05-15 15:43:59 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 			if ((tb_scale.h != 0.0f) && | 
					
						
							| 
									
										
										
										
											2015-09-10 14:07:37 +10:00
										 |  |  | 			    ((-(yof - tb_scale.y)) > (tb_scale.h - linedist) - yof_scale)) | 
					
						
							| 
									
										
										
										
											2012-05-20 19:49:27 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				if (cu->totbox > (curbox + 1)) { | 
					
						
							|  |  |  | 					maxlen = 0; | 
					
						
							|  |  |  | 					curbox++; | 
					
						
							|  |  |  | 					i_textbox_array[curbox] = i + 1; | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 					textbox_scale(&tb_scale, &cu->tb[curbox], 1.0f / font_size); | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 					yof = MARGIN_Y_MIN; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else if (last_line == -1) { | 
					
						
							|  |  |  | 					last_line = lnr + 1; | 
					
						
							|  |  |  | 					info->flag |= CU_CHINFO_OVERFLOW; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			current_line_length += xof; | 
					
						
							|  |  |  | 			if (ct->dobreak) { | 
					
						
							|  |  |  | 				current_line_length += twidth; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				longest_line_length = MAX2(current_line_length, longest_line_length); | 
					
						
							|  |  |  | 				current_line_length = 0.0f; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-08 12:43:44 +00:00
										 |  |  | 			/* XXX, has been unused for years, need to check if this is useful, r4613 r5282 - campbell */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 			if (ascii == '\n') | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 				xof = xof_scale; | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 				xof = MARGIN_X_MIN; | 
					
						
							| 
									
										
										
										
											2011-01-08 12:43:44 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 			xof = MARGIN_X_MIN; | 
					
						
							| 
									
										
										
										
											2011-01-08 12:43:44 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			lnr++; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			cnr = 0; | 
					
						
							|  |  |  | 			wsnr = 0; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		else if (ascii == 9) {    /* TAB */ | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | 			float tabfac; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			ct->xof = xof; | 
					
						
							|  |  |  | 			ct->yof = yof; | 
					
						
							|  |  |  | 			ct->linenr = lnr; | 
					
						
							|  |  |  | 			ct->charnr = cnr++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 			tabfac = (xof - MARGIN_X_MIN + 0.01f); | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			tabfac = 2.0f * ceilf(tabfac / 2.0f); | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 			xof = MARGIN_X_MIN + tabfac; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2014-01-07 17:04:19 +11:00
										 |  |  | 			EditFontSelBox *sb = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | 			float wsfac; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			ct->xof = xof; | 
					
						
							|  |  |  | 			ct->yof = yof; | 
					
						
							|  |  |  | 			ct->linenr = lnr; | 
					
						
							|  |  |  | 			ct->charnr = cnr++; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:04:19 +11:00
										 |  |  | 			if (selboxes && (i >= selstart) && (i <= selend)) { | 
					
						
							|  |  |  | 				sb = &selboxes[i - selstart]; | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				sb->y = yof * font_size - linedist * font_size * 0.1f; | 
					
						
							|  |  |  | 				sb->h = linedist * font_size; | 
					
						
							|  |  |  | 				sb->w = xof * font_size; | 
					
						
							| 
									
										
										
										
											2005-10-28 15:36:09 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			if (ascii == 32) { | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 				wsfac = cu->wordspace; | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 				wsnr++; | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 			else { | 
					
						
							|  |  |  | 				wsfac = 1.0f; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 			/* Set the width of the character */ | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | 			twidth = char_width(cu, che, info); | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			xof += (twidth * wsfac * (1.0f + (info->kern / 40.0f)) ) + xtrax; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 			if (sb) { | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				sb->w = (xof * font_size) - sb->w; | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		ct++; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 	current_line_length += xof + twidth; | 
					
						
							|  |  |  | 	longest_line_length = MAX2(current_line_length, longest_line_length); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	cu->lines = 1; | 
					
						
							| 
									
										
										
										
											2014-01-05 20:52:31 +11:00
										 |  |  | 	for (i = 0; i <= slen; i++) { | 
					
						
							|  |  |  | 		ascii = mem[i]; | 
					
						
							|  |  |  | 		ct = &chartransdata[i]; | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 		if (ascii == '\n' || ct->dobreak) cu->lines++; | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-07-29 13:36:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 	/* linedata is now: width of line */ | 
					
						
							| 
									
										
										
										
											2003-07-29 13:36:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 12:44:49 +10:00
										 |  |  | 	if (cu->spacemode != CU_ALIGN_X_LEFT) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		ct = chartransdata; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 12:44:49 +10:00
										 |  |  | 		if (cu->spacemode == CU_ALIGN_X_RIGHT) { | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 			struct TempLineInfo *li; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (i = 0, li = lineinfo; i < lnr; i++, li++) { | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 				li->x_min = (li->x_max - li->x_min) + xof_scale; | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			for (i = 0; i <= slen; i++) { | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 				ct->xof += lineinfo[ct->linenr].x_min; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				ct++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-21 12:44:49 +10:00
										 |  |  | 		else if (cu->spacemode == CU_ALIGN_X_MIDDLE) { | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 			struct TempLineInfo *li; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (i = 0, li = lineinfo; i < lnr; i++, li++) { | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 				li->x_min = ((li->x_max - li->x_min) + xof_scale) / 2.0f; | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			for (i = 0; i <= slen; i++) { | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 				ct->xof += lineinfo[ct->linenr].x_min; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				ct++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-21 12:44:49 +10:00
										 |  |  | 		else if ((cu->spacemode == CU_ALIGN_X_FLUSH) && use_textbox) { | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 			struct TempLineInfo *li; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (i = 0, li = lineinfo; i < lnr; i++, li++) { | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 				li->x_min = ((li->x_max - li->x_min) + xof_scale); | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (li->char_nr > 1) { | 
					
						
							|  |  |  | 					li->x_min /= (float)(li->char_nr - 1); | 
					
						
							| 
									
										
										
										
											2014-05-15 21:59:16 +10:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			for (i = 0; i <= slen; i++) { | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 				for (j = i; (!ELEM(mem[j], '\0', '\n')) && (chartransdata[j].dobreak == 0) && (j < slen); j++) { | 
					
						
							| 
									
										
										
										
											2012-02-25 09:06:17 +00:00
										 |  |  | 					/* do nothing */ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | //				if ((mem[j] != '\n') && (mem[j])) {
 | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 				ct->xof += ct->charnr * lineinfo[ct->linenr].x_min; | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | //				}
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				ct++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-21 12:44:49 +10:00
										 |  |  | 		else if ((cu->spacemode == CU_ALIGN_X_JUSTIFY) && use_textbox) { | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 			float curofs = 0.0f; | 
					
						
							|  |  |  | 			for (i = 0; i <= slen; i++) { | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 				for (j = i; | 
					
						
							|  |  |  | 				     (mem[j]) && (mem[j] != '\n') && (chartransdata[j].dobreak == 0) && (j < slen); | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 				     j++) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					/* pass */ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 				if ((mem[j] != '\n') && | 
					
						
							| 
									
										
										
										
											2012-05-20 19:49:27 +00:00
										 |  |  | 				    ((chartransdata[j].dobreak != 0))) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 					if (mem[i] == ' ') { | 
					
						
							|  |  |  | 						struct TempLineInfo *li; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						li = &lineinfo[ct->linenr]; | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 						curofs += ((li->x_max - li->x_min) + xof_scale) / (float)li->wspace_nr; | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 					ct->xof += curofs; | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 				if (mem[i] == '\n' || chartransdata[i].dobreak) curofs = 0; | 
					
						
							| 
									
										
											  
											
												
More text object fancyness, and fixes:
 - "Flush" is now split into two seperate Alignment modes "Flush" and
   "Justify":
   - Justify does exactly the same as a normal word processor's justify
     function does, and in addition, it uses *whitespace* instead of
     *character spacing* (kerning) to fill lines. Much more readable.
   - Flush is pretty much the old Blender "Flush" mode - and as such it
     uses character spacing to fill lines. Just as Justify, this only
     works with at least one textframe.
 - Underlining for text objects. Not a lot to explain. New button "U" in
   the editbuttons, and CTRL-U as hotkey toggle underlining for newly
   entered characters or for the selection, just like CTRL-B/CTRL-I do for
   bold/italic.
   Underline height (thickness) and Underline position (vertical) can be
   set in the editbuttons.
   Implemented as CU_POLY polygon curves.
 - The B, U and i buttons (and the corresponding CTRL-B/U/I keystrokes)
   have been fixed to only affect *one* attribute at a time. Formerly,
   hitting CTRL-B when no other style was active, on a text portion with
   italics text, for example, would kill the italics and just apply bold.
   Now, these attributes always add or substract only, but do not
   replace the style.
 - In the past, there were bugs with material indices uninitialized, and
   thus crashes in the renderer with illegal material indices.
   Even though I assume they have been fixed, I've put in a check that
   checks (hah) if the material index of a character is illegal (bigger
   than ob->totcol), and then sets it to zero, and spits out a warning
   on stderr.
   If you see such warnings, please report and link to the .blend.
 - Bugfix: All alignment modes only worked if there were at least *two*
   lines of text in the text object. Fixed
There's now a regression test file for text objects, please add to the
corresponding repository:
http://blender.instinctive.de/downloads/release/demo/text-regression.blend.gz
											
										 
											2005-08-29 12:46:07 +00:00
										 |  |  | 				ct++; | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-20 23:21:24 -03:00
										 |  |  | 	/* top-baseline is default, in this case, do nothing */ | 
					
						
							|  |  |  | 	if (cu->align_y != CU_ALIGN_Y_TOP_BASELINE) { | 
					
						
							|  |  |  | 		if (tb_scale.h != 0.0f) { | 
					
						
							| 
									
										
										
										
											2018-09-10 18:13:08 -03:00
										 |  |  | 			/* We need to loop all the text-boxes even the "full" ones.
 | 
					
						
							|  |  |  | 			 * This way they all get the same vertical padding. */ | 
					
						
							|  |  |  | 			for (int tb_index = 0; tb_index < cu->totbox; tb_index++) { | 
					
						
							|  |  |  | 				struct CharTrans *ct_first, *ct_last; | 
					
						
							|  |  |  | 				const int i_textbox = i_textbox_array[tb_index]; | 
					
						
							|  |  |  | 				const int i_textbox_next = i_textbox_array[tb_index + 1]; | 
					
						
							|  |  |  | 				const bool is_last_filled_textbox = ELEM(i_textbox_next, 0, slen + 1); | 
					
						
							| 
									
										
										
										
											2018-09-05 10:01:08 -03:00
										 |  |  | 				int lines; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-10 18:13:08 -03:00
										 |  |  | 				ct_first = chartransdata + i_textbox; | 
					
						
							|  |  |  | 				ct_last = chartransdata + (is_last_filled_textbox ? slen: i_textbox_next - 1); | 
					
						
							|  |  |  | 				lines = ct_last->linenr - ct_first->linenr + 1; | 
					
						
							| 
									
										
										
										
											2016-06-20 23:21:24 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				textbox_scale(&tb_scale, &cu->tb[tb_index], 1.0f / font_size); | 
					
						
							| 
									
										
										
										
											2018-09-24 18:46:51 +02:00
										 |  |  | 				/* The initial Y origin of the textbox is hardcoded to 1.0f * text scale. */ | 
					
						
							| 
									
										
										
										
											2018-09-05 11:21:12 +10:00
										 |  |  | 				const float textbox_y_origin = 1.0f; | 
					
						
							| 
									
										
										
										
											2018-10-23 12:50:31 +02:00
										 |  |  | 				float yoff = 0.0f; | 
					
						
							| 
									
										
										
										
											2016-06-20 23:21:24 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-05 11:21:12 +10:00
										 |  |  | 				switch (cu->align_y) { | 
					
						
							|  |  |  | 					case CU_ALIGN_Y_TOP_BASELINE: | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					case CU_ALIGN_Y_TOP: | 
					
						
							|  |  |  | 						yoff = textbox_y_origin - ASCENT(vfd); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					case CU_ALIGN_Y_CENTER: | 
					
						
							| 
									
										
										
										
											2018-09-05 10:01:08 -03:00
										 |  |  | 						yoff = ((((vfd->em_height + (lines - 1) * linedist) * 0.5f) - ASCENT(vfd)) - | 
					
						
							| 
									
										
										
										
											2018-09-05 11:21:12 +10:00
										 |  |  | 						        (tb_scale.h  * 0.5f) + textbox_y_origin); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					case CU_ALIGN_Y_BOTTOM_BASELINE: | 
					
						
							| 
									
										
										
										
											2018-09-05 10:01:08 -03:00
										 |  |  | 						yoff = textbox_y_origin + ((lines - 1) * linedist) - tb_scale.h; | 
					
						
							| 
									
										
										
										
											2018-09-05 11:21:12 +10:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					case CU_ALIGN_Y_BOTTOM: | 
					
						
							| 
									
										
										
										
											2018-09-05 10:01:08 -03:00
										 |  |  | 						yoff = textbox_y_origin + ((lines - 1) * linedist) - tb_scale.h + DESCENT(vfd); | 
					
						
							| 
									
										
										
										
											2018-09-05 11:21:12 +10:00
										 |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2016-06-20 23:21:24 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-10 18:13:08 -03:00
										 |  |  | 				for (ct = ct_first; ct <= ct_last; ct++) { | 
					
						
							| 
									
										
										
										
											2016-06-20 23:21:24 -03:00
										 |  |  | 					ct->yof += yoff; | 
					
						
							| 
									
										
										
										
											2018-09-10 18:13:08 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (is_last_filled_textbox) { | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2016-06-20 23:21:24 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2018-09-05 11:21:12 +10:00
										 |  |  | 			/* Non text-box case handled separately. */ | 
					
						
							| 
									
										
										
										
											2018-10-23 12:50:31 +02:00
										 |  |  | 			float yoff = 0.0f; | 
					
						
							| 
									
										
										
										
											2016-06-20 23:21:24 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-05 11:21:12 +10:00
										 |  |  | 			switch (cu->align_y) { | 
					
						
							|  |  |  | 				case CU_ALIGN_Y_TOP_BASELINE: | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case CU_ALIGN_Y_TOP: | 
					
						
							|  |  |  | 					yoff = -ASCENT(vfd); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case CU_ALIGN_Y_CENTER: | 
					
						
							|  |  |  | 					yoff = ((vfd->em_height + (lnr - 1) * linedist) * 0.5f) - ASCENT(vfd); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case CU_ALIGN_Y_BOTTOM_BASELINE: | 
					
						
							|  |  |  | 					yoff = (lnr - 1) * linedist; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case CU_ALIGN_Y_BOTTOM: | 
					
						
							|  |  |  | 					yoff = (lnr - 1) * linedist + DESCENT(vfd); | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2016-06-20 23:21:24 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-10 18:13:08 -03:00
										 |  |  | 			ct = chartransdata; | 
					
						
							| 
									
										
										
										
											2016-06-20 23:21:24 -03:00
										 |  |  | 			for (i = 0; i <= slen; i++) { | 
					
						
							|  |  |  | 				ct->yof += yoff; | 
					
						
							|  |  |  | 				ct++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 	MEM_freeN(lineinfo); | 
					
						
							| 
									
										
										
										
											2018-09-10 18:13:08 -03:00
										 |  |  | 	MEM_freeN(i_textbox_array); | 
					
						
							| 
									
										
										
										
											2014-05-16 07:45:13 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	/* TEXT ON CURVE */ | 
					
						
							| 
									
										
										
										
											2010-03-13 11:22:39 +00:00
										 |  |  | 	/* Note: Only OB_CURVE objects could have a path  */ | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 	if (cu->textoncurve && cu->textoncurve->type == OB_CURVE) { | 
					
						
							| 
									
										
										
										
											2018-07-30 16:54:40 +02:00
										 |  |  | 		BLI_assert(cu->textoncurve->runtime.curve_cache != NULL); | 
					
						
							| 
									
										
										
										
											2018-10-09 11:07:58 +02:00
										 |  |  | 		if (cu->textoncurve->runtime.curve_cache != NULL && cu->textoncurve->runtime.curve_cache->path != NULL) { | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | 			float distfac, imat[4][4], imat3[3][3], cmat[3][3]; | 
					
						
							|  |  |  | 			float minx, maxx, miny, maxy; | 
					
						
							|  |  |  | 			float timeofs, sizefac; | 
					
						
							| 
									
										
										
										
											2018-02-09 10:13:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (ob != NULL) { | 
					
						
							|  |  |  | 				invert_m4_m4(imat, ob->obmat); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				unit_m4(imat); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 			copy_m3_m4(imat3, imat); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 			copy_m3_m4(cmat, cu->textoncurve->obmat); | 
					
						
							|  |  |  | 			mul_m3_m3m3(cmat, cmat, imat3); | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 			sizefac = normalize_v3(cmat[0]) / font_size; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			minx = miny = 1.0e20f; | 
					
						
							|  |  |  | 			maxx = maxy = -1.0e20f; | 
					
						
							|  |  |  | 			ct = chartransdata; | 
					
						
							|  |  |  | 			for (i = 0; i <= slen; i++, ct++) { | 
					
						
							|  |  |  | 				if (minx > ct->xof) minx = ct->xof; | 
					
						
							|  |  |  | 				if (maxx < ct->xof) maxx = ct->xof; | 
					
						
							|  |  |  | 				if (miny > ct->yof) miny = ct->yof; | 
					
						
							|  |  |  | 				if (maxy < ct->yof) maxy = ct->yof; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-26 11:56:44 +00:00
										 |  |  | 			/* we put the x-coordinaat exact at the curve, the y is rotated */ | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-26 11:56:44 +00:00
										 |  |  | 			/* length correction */ | 
					
						
							| 
									
										
										
										
											2018-07-30 16:54:40 +02:00
										 |  |  | 			distfac = sizefac * cu->textoncurve->runtime.curve_cache->path->totdist / (maxx - minx); | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			timeofs = 0.0f; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			if (distfac > 1.0f) { | 
					
						
							| 
									
										
										
										
											2003-04-26 11:56:44 +00:00
										 |  |  | 				/* path longer than text: spacemode involves */ | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				distfac = 1.0f / distfac; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 12:44:49 +10:00
										 |  |  | 				if (cu->spacemode == CU_ALIGN_X_RIGHT) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 					timeofs = 1.0f - distfac; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-06-21 12:44:49 +10:00
										 |  |  | 				else if (cu->spacemode == CU_ALIGN_X_MIDDLE) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 					timeofs = (1.0f - distfac) / 2.0f; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-06-21 12:44:49 +10:00
										 |  |  | 				else if (cu->spacemode == CU_ALIGN_X_FLUSH) { | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 					distfac = 1.0f; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 			else { | 
					
						
							|  |  |  | 				distfac = 1.0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			distfac /= (maxx - minx); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			timeofs += distfac * cu->xof;  /* not cyclic */ | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			ct = chartransdata; | 
					
						
							| 
									
										
										
										
											2019-01-29 22:50:55 +11:00
										 |  |  | 			for (i = 0; i <= slen; i++, ct++) { | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | 				float ctime, dtime, vec[4], tvec[4], rotvec[3]; | 
					
						
							|  |  |  | 				float si, co; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-04 13:18:41 +00:00
										 |  |  | 				/* rotate around center character */ | 
					
						
							| 
									
										
										
										
											2014-01-05 20:50:15 +11:00
										 |  |  | 				info = &custrinfo[i]; | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 				ascii = mem[i]; | 
					
						
							| 
									
										
										
										
											2014-01-05 20:52:31 +11:00
										 |  |  | 				if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) { | 
					
						
							|  |  |  | 					ascii = towupper(ascii); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-07-13 23:51:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				che = find_vfont_char(vfd, ascii); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 22:21:59 +00:00
										 |  |  | 				twidth = char_width(cu, che, info); | 
					
						
							| 
									
										
										
										
											2011-01-14 21:06:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				dtime = distfac * 0.5f * twidth; | 
					
						
							| 
									
										
										
										
											2011-01-14 21:06:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				ctime = timeofs + distfac * (ct->xof - minx); | 
					
						
							| 
									
										
										
										
											2011-03-28 11:21:39 +00:00
										 |  |  | 				CLAMP(ctime, 0.0f, 1.0f); | 
					
						
							| 
									
										
										
										
											2003-04-26 11:56:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* calc the right loc AND the right rot separately */ | 
					
						
							| 
									
										
										
										
											2004-11-21 10:42:42 +00:00
										 |  |  | 				/* vec, tvec need 4 items */ | 
					
						
							| 
									
										
										
										
											2010-04-21 11:59:47 +00:00
										 |  |  | 				where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				where_on_path(cu->textoncurve, ctime + dtime, tvec, rotvec, NULL, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 				mul_v3_fl(vec, sizefac); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 				ct->rot = (float)M_PI - atan2f(rotvec[1], rotvec[0]); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-04 19:34:38 +00:00
										 |  |  | 				si = sinf(ct->rot); | 
					
						
							|  |  |  | 				co = cosf(ct->rot); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				yof = ct->yof; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				ct->xof = vec[0] + si * yof; | 
					
						
							|  |  |  | 				ct->yof = vec[1] + co * yof; | 
					
						
							| 
									
										
										
										
											2014-01-05 22:12:21 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:04:19 +11:00
										 |  |  | 				if (selboxes && (i >= selstart) && (i <= selend)) { | 
					
						
							|  |  |  | 					EditFontSelBox *sb; | 
					
						
							|  |  |  | 					sb = &selboxes[i - selstart]; | 
					
						
							| 
									
										
										
										
											2014-01-05 22:12:21 +11:00
										 |  |  | 					sb->rot = -ct->rot; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:04:19 +11:00
										 |  |  | 	if (selboxes) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		ct = chartransdata; | 
					
						
							|  |  |  | 		for (i = 0; i <= selend; i++, ct++) { | 
					
						
							|  |  |  | 			if (i >= selstart) { | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				selboxes[i - selstart].x = ct->xof * font_size; | 
					
						
							|  |  |  | 				selboxes[i - selstart].y = ct->yof * font_size; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-28 11:18:09 +11:00
										 |  |  | 	if (ELEM(mode, FO_CURSUP, FO_CURSDOWN, FO_PAGEUP, FO_PAGEDOWN) && | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 	    iter_data->status == VFONT_TO_CURVE_INIT) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 		ct = &chartransdata[ef->pos]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-31 21:29:37 -03:00
										 |  |  | 		if (ELEM(mode, FO_CURSUP, FO_PAGEUP) && ct->linenr == 0) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 			/* pass */ | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-10-31 21:29:37 -03:00
										 |  |  | 		else if (ELEM(mode, FO_CURSDOWN, FO_PAGEDOWN) && ct->linenr == lnr) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 			/* pass */ | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 			switch (mode) { | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 				case FO_CURSUP:     lnr = ct->linenr - 1; break; | 
					
						
							|  |  |  | 				case FO_CURSDOWN:   lnr = ct->linenr + 1; break; | 
					
						
							|  |  |  | 				case FO_PAGEUP:     lnr = ct->linenr - 10; break; | 
					
						
							|  |  |  | 				case FO_PAGEDOWN:   lnr = ct->linenr + 10; break; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			cnr = ct->charnr; | 
					
						
							| 
									
										
										
										
											2003-04-26 11:56:44 +00:00
										 |  |  | 			/* seek for char with lnr en cnr */ | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 			ef->pos = 0; | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 			ct = chartransdata; | 
					
						
							|  |  |  | 			for (i = 0; i < slen; i++) { | 
					
						
							|  |  |  | 				if (ct->linenr == lnr) { | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 					if ((ct->charnr == cnr) || ((ct + 1)->charnr == 0)) { | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else if (ct->linenr > lnr) { | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 				ef->pos++; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 				ct++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-26 11:56:44 +00:00
										 |  |  | 	/* cursor first */ | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 	if (ef) { | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | 		float si, co; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 		ct = &chartransdata[ef->pos]; | 
					
						
							| 
									
										
										
										
											2013-01-12 14:28:23 +00:00
										 |  |  | 		si = sinf(ct->rot); | 
					
						
							|  |  |  | 		co = cosf(ct->rot); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 		f = ef->textcurs[0]; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 		f[0] = font_size * (-0.1f * co + ct->xof); | 
					
						
							|  |  |  | 		f[1] = font_size * ( 0.1f * si + ct->yof); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 		f[2] = font_size * ( 0.1f * co + ct->xof); | 
					
						
							|  |  |  | 		f[3] = font_size * (-0.1f * si + ct->yof); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 		f[4] = font_size * ( 0.1f * co + 0.8f * si + ct->xof); | 
					
						
							|  |  |  | 		f[5] = font_size * (-0.1f * si + 0.8f * co + ct->yof); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 		f[6] = font_size * (-0.1f * co + 0.8f * si + ct->xof); | 
					
						
							|  |  |  | 		f[7] = font_size * ( 0.1f * si + 0.8f * co + ct->yof); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 	if (mode == FO_SELCHANGE) { | 
					
						
							|  |  |  | 		MEM_freeN(chartransdata); | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 		chartransdata = NULL; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 	else if (mode == FO_EDIT) { | 
					
						
							| 
									
										
										
										
											2003-04-26 11:56:44 +00:00
										 |  |  | 		/* make nurbdata */ | 
					
						
							| 
									
										
										
										
											2014-01-06 01:33:45 +11:00
										 |  |  | 		BKE_nurbList_free(r_nubase); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 15:15:33 +00:00
										 |  |  | 		ct = chartransdata; | 
					
						
							| 
									
										
										
										
											2014-01-05 20:15:39 +11:00
										 |  |  | 		for (i = 0; i < slen; i++) { | 
					
						
							|  |  |  | 			unsigned int cha = (unsigned int) mem[i]; | 
					
						
							|  |  |  | 			info = &(custrinfo[i]); | 
					
						
							| 
									
										
										
										
											2014-01-05 20:52:31 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 			if ((cu->overflow == CU_OVERFLOW_TRUNCATE) && | 
					
						
							|  |  |  | 			    (ob && ob->mode != OB_MODE_EDIT) && | 
					
						
							|  |  |  | 			    (info->flag & CU_CHINFO_OVERFLOW)) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-05 20:52:31 +11:00
										 |  |  | 			if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) { | 
					
						
							|  |  |  | 				cha = towupper(cha); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 15:08:29 +01:00
										 |  |  | 			if (ob == NULL || info->mat_nr > (ob->totcol)) { | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | 				/* CLOG_ERROR(&LOG, "Illegal material index (%d) in text object, setting to 0", info->mat_nr); */ | 
					
						
							| 
									
										
										
										
											2014-01-05 20:15:39 +11:00
										 |  |  | 				info->mat_nr = 0; | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-01-05 20:15:39 +11:00
										 |  |  | 			/* We do not want to see any character for \n or \r */ | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 			if (cha != '\n') | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				buildchar(cu, r_nubase, cha, info, ct->xof, ct->yof, ct->rot, i, font_size); | 
					
						
							| 
									
										
										
										
											2014-01-05 20:15:39 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 			if ((info->flag & CU_CHINFO_UNDERLINE) && (cha != '\n')) { | 
					
						
							| 
									
										
										
										
											2014-01-05 20:15:39 +11:00
										 |  |  | 				float ulwidth, uloverlap = 0.0f; | 
					
						
							| 
									
										
										
										
											2014-01-07 23:04:47 +11:00
										 |  |  | 				rctf rect; | 
					
						
							| 
									
										
										
										
											2014-01-05 20:15:39 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 18:04:50 +10:00
										 |  |  | 				if ((i < (slen - 1)) && (mem[i + 1] != '\n') && | 
					
						
							| 
									
										
										
										
											2014-01-05 20:15:39 +11:00
										 |  |  | 				    ((mem[i + 1] != ' ') || (custrinfo[i + 1].flag & CU_CHINFO_UNDERLINE)) && | 
					
						
							|  |  |  | 				    ((custrinfo[i + 1].flag & CU_CHINFO_WRAP) == 0)) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					uloverlap = xtrax + 0.1f; | 
					
						
							| 
									
										
										
										
											2005-06-17 21:04:27 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-01-05 20:15:39 +11:00
										 |  |  | 				/* Find the character, the characters has to be in the memory already
 | 
					
						
							|  |  |  | 				 * since character checking has been done earlier already. */ | 
					
						
							|  |  |  | 				che = find_vfont_char(vfd, cha); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				twidth = char_width(cu, che, info); | 
					
						
							| 
									
										
										
										
											2014-01-07 23:04:47 +11:00
										 |  |  | 				ulwidth = (twidth * (1.0f + (info->kern / 40.0f))) + uloverlap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				rect.xmin = ct->xof; | 
					
						
							|  |  |  | 				rect.xmax = rect.xmin + ulwidth; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				rect.ymin = ct->yof; | 
					
						
							|  |  |  | 				rect.ymax = rect.ymin - cu->ulheight; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-06 01:33:45 +11:00
										 |  |  | 				build_underline(cu, r_nubase, | 
					
						
							| 
									
										
										
										
											2014-01-07 23:04:47 +11:00
										 |  |  | 				                &rect, cu->ulpos - 0.05f, | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				                ct->rot, i, info->mat_nr, | 
					
						
							|  |  |  | 				                font_size); | 
					
						
							| 
									
										
										
										
											2009-01-23 14:43:25 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-01-05 20:15:39 +11:00
										 |  |  | 			ct++; | 
					
						
							| 
									
										
										
										
											2005-09-19 17:58:51 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 	if (iter_data->status == VFONT_TO_CURVE_SCALE_ONCE) { | 
					
						
							|  |  |  | 		/* That means we were in a final run, just exit. */ | 
					
						
							|  |  |  | 		BLI_assert(cu->overflow == CU_OVERFLOW_SCALE); | 
					
						
							|  |  |  | 		iter_data->status = VFONT_TO_CURVE_DONE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (cu->overflow == CU_OVERFLOW_NONE) { | 
					
						
							|  |  |  | 		/* Do nothing. */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if ((tb_scale.h == 0.0f) && (tb_scale.w == 0.0f)) { | 
					
						
							|  |  |  | 		/* Do nothing. */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (cu->overflow == CU_OVERFLOW_SCALE) { | 
					
						
							|  |  |  | 		if ((cu->totbox == 1) && ((tb_scale.w == 0.0f) || (tb_scale.h == 0.0f))) { | 
					
						
							|  |  |  | 			/* These are special cases, simpler to deal with. */ | 
					
						
							|  |  |  | 			if (tb_scale.w == 0.0f) { | 
					
						
							|  |  |  | 				/* This is a potential vertical overflow.
 | 
					
						
							|  |  |  | 				 * Since there is no width limit, all the new lines are from line breaks. */ | 
					
						
							|  |  |  | 				if ((last_line != -1) && (lnr > last_line)) { | 
					
						
							|  |  |  | 					const float total_text_height = lnr * linedist; | 
					
						
							|  |  |  | 					iter_data->scale_to_fit = tb_scale.h / total_text_height; | 
					
						
							|  |  |  | 					iter_data->status = VFONT_TO_CURVE_SCALE_ONCE; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else if (tb_scale.h == 0.0f) { | 
					
						
							|  |  |  | 				/* This is a horizontal overflow. */ | 
					
						
							|  |  |  | 				if (lnr > 1) { | 
					
						
							|  |  |  | 					/* We make sure longest line before it broke can fit here. */ | 
					
						
							|  |  |  | 					float scale_to_fit = tb_scale.w / (longest_line_length); | 
					
						
							|  |  |  | 					scale_to_fit -= FLT_EPSILON; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					iter_data->scale_to_fit = scale_to_fit; | 
					
						
							|  |  |  | 					iter_data->status = VFONT_TO_CURVE_SCALE_ONCE; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			/* This is the really complicated case, the best we can do is to iterate over
 | 
					
						
							|  |  |  | 			 * this function a few times until we get an acceptable result. | 
					
						
							|  |  |  | 			 * | 
					
						
							|  |  |  | 			 * Keep in mind that there is no single number that will make all fit to the end. | 
					
						
							|  |  |  | 			 * In a way, our ultimate goal is to get the highest scale that still leads to the | 
					
						
							|  |  |  | 			 * number of extra lines to zero. | 
					
						
							|  |  |  | 			 */ | 
					
						
							|  |  |  | 			if (iter_data->status == VFONT_TO_CURVE_INIT) { | 
					
						
							|  |  |  | 				bool valid = true; | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 				for (int tb_index = 0; tb_index <= curbox; tb_index++) { | 
					
						
							|  |  |  | 					TextBox *tb = &cu->tb[tb_index]; | 
					
						
							|  |  |  | 					if ((tb->w == 0.0f) || (tb->h == 0.0f)) { | 
					
						
							|  |  |  | 						valid = false; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (valid && (last_line != -1) && (lnr > last_line)) { | 
					
						
							|  |  |  | 					const float total_text_height = lnr * linedist; | 
					
						
							|  |  |  | 					float scale_to_fit = tb_scale.h / total_text_height; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 					iter_data->bisect.max = 1.0f; | 
					
						
							|  |  |  | 					iter_data->bisect.min = scale_to_fit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					iter_data->status = VFONT_TO_CURVE_BISECT; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				BLI_assert(iter_data->status == VFONT_TO_CURVE_BISECT); | 
					
						
							|  |  |  | 				/* Try to get the highest scale that gives us the exactly
 | 
					
						
							|  |  |  | 				 * number of lines we need. */ | 
					
						
							|  |  |  | 				bool valid = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if ((last_line != -1) && (lnr > last_line)) { | 
					
						
							|  |  |  | 					/* It is overflowing, scale it down. */ | 
					
						
							|  |  |  | 					iter_data->bisect.max = iter_data->scale_to_fit; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					/* It fits inside the textbox, scale it up. */ | 
					
						
							|  |  |  | 					iter_data->bisect.min = iter_data->scale_to_fit; | 
					
						
							|  |  |  | 					valid = true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Bisecting to try to find the best fit. */ | 
					
						
							|  |  |  | 				iter_data->scale_to_fit = (iter_data->bisect.max + iter_data->bisect.min) * 0.5f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* We iterated enough or got a good enough result. */ | 
					
						
							|  |  |  | 				if ((!iter_data->iteraction--) || | 
					
						
							|  |  |  | 				    ((iter_data->bisect.max - iter_data->bisect.min) < (cu->fsize * FONT_TO_CURVE_SCALE_THRESHOLD))) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					if (valid) { | 
					
						
							|  |  |  | 						iter_data->status = VFONT_TO_CURVE_DONE; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						iter_data->scale_to_fit = iter_data->bisect.min; | 
					
						
							|  |  |  | 						iter_data->status = VFONT_TO_CURVE_SCALE_ONCE; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Scale to fit only works for single text box layouts. */ | 
					
						
							|  |  |  | 	if (ELEM(iter_data->status, | 
					
						
							|  |  |  | 	         VFONT_TO_CURVE_SCALE_ONCE, | 
					
						
							|  |  |  | 	         VFONT_TO_CURVE_BISECT)) | 
					
						
							| 
									
										
										
										
											2014-01-06 01:33:45 +11:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 		/* Always cleanup before going to the scale-to-fit repetition. */ | 
					
						
							|  |  |  | 		if (r_nubase != NULL) { | 
					
						
							|  |  |  | 			BKE_nurbList_free(r_nubase); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (chartransdata != NULL) { | 
					
						
							|  |  |  | 			MEM_freeN(chartransdata); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (ef == NULL) { | 
					
						
							|  |  |  | 			MEM_freeN((void *)mem); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		ok = true; | 
					
						
							|  |  |  | finally: | 
					
						
							| 
									
										
										
										
											2014-01-06 01:33:45 +11:00
										 |  |  | 		if (r_text) { | 
					
						
							|  |  |  | 			*r_text = mem; | 
					
						
							|  |  |  | 			*r_text_len = slen; | 
					
						
							|  |  |  | 			*r_text_free = (ef == NULL); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			if (ef == NULL) { | 
					
						
							|  |  |  | 				MEM_freeN((void *)mem); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-09-14 14:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 		if (chartransdata) { | 
					
						
							|  |  |  | 			if (ok && r_chartransdata) { | 
					
						
							|  |  |  | 				*r_chartransdata = chartransdata; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				MEM_freeN(chartransdata); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-01-03 17:04:42 +11:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | 		/* Store the effective scale, to use for the textbox lines. */ | 
					
						
							|  |  |  | 		cu->fsize_realtime = font_size; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-03 14:18:06 +11:00
										 |  |  | 	return ok; | 
					
						
							| 
									
										
										
										
											2014-05-16 10:27:52 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef MARGIN_X_MIN
 | 
					
						
							|  |  |  | #undef MARGIN_Y_MIN
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-01-05 17:04:52 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-05 11:21:12 +10:00
										 |  |  | #undef DESCENT
 | 
					
						
							|  |  |  | #undef ASCENT
 | 
					
						
							| 
									
										
										
										
											2014-01-06 01:33:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 13:00:30 -03:00
										 |  |  | bool BKE_vfont_to_curve_ex(Object *ob, Curve *cu, int mode, ListBase *r_nubase, | 
					
						
							|  |  |  |                            const wchar_t **r_text, int *r_text_len, bool *r_text_free, | 
					
						
							|  |  |  |                            struct CharTrans **r_chartransdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	VFontToCurveIter data = { | 
					
						
							|  |  |  | 		.iteraction = cu->totbox * FONT_TO_CURVE_SCALE_ITERATIONS, | 
					
						
							|  |  |  | 		.scale_to_fit = 1.0f, | 
					
						
							|  |  |  | 		.ok = true, | 
					
						
							|  |  |  | 		.status = VFONT_TO_CURVE_INIT, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do { | 
					
						
							|  |  |  | 		data.ok &= vfont_to_curve(ob, | 
					
						
							|  |  |  | 		                          cu, | 
					
						
							|  |  |  | 		                          mode, | 
					
						
							|  |  |  | 		                          &data, | 
					
						
							|  |  |  | 		                          r_nubase, | 
					
						
							|  |  |  | 		                          r_text, | 
					
						
							|  |  |  | 		                          r_text_len, | 
					
						
							|  |  |  | 		                          r_text_free, | 
					
						
							|  |  |  | 		                          r_chartransdata); | 
					
						
							|  |  |  | 	} while (data.ok && ELEM(data.status, | 
					
						
							|  |  |  | 	                         VFONT_TO_CURVE_SCALE_ONCE, | 
					
						
							|  |  |  | 	                         VFONT_TO_CURVE_BISECT)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return data.ok; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef FONT_TO_CURVE_SCALE_ITERATIONS
 | 
					
						
							|  |  |  | #undef FONT_TO_CURVE_SCALE_THRESHOLD
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | bool BKE_vfont_to_curve_nubase(Object *ob, int mode, ListBase *r_nubase) | 
					
						
							| 
									
										
										
										
											2014-01-06 01:33:45 +11:00
										 |  |  | { | 
					
						
							|  |  |  | 	BLI_assert(ob->type == OB_FONT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | 	return BKE_vfont_to_curve_ex(ob, ob->data, mode, r_nubase, | 
					
						
							| 
									
										
										
										
											2014-01-06 01:48:25 +11:00
										 |  |  | 	                             NULL, NULL, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2014-01-06 01:33:45 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-30 21:36:02 +02:00
										 |  |  | /** Warning: expects to have access to evaluated data (i.e. passed object should be evaluated one...). */ | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | bool BKE_vfont_to_curve(Object *ob, int mode) | 
					
						
							| 
									
										
										
										
											2014-01-06 01:33:45 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-01-06 01:48:25 +11:00
										 |  |  | 	Curve *cu = ob->data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 15:03:51 +02:00
										 |  |  | 	return BKE_vfont_to_curve_ex(ob, ob->data, mode, &cu->nurb, NULL, NULL, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2014-01-05 17:04:52 +06:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-02-12 10:57:58 -02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name VFont Clipboard
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct { | 
					
						
							|  |  |  | 	wchar_t *text_buffer; | 
					
						
							|  |  |  | 	CharInfo *info_buffer; | 
					
						
							|  |  |  | 	size_t len_wchar; | 
					
						
							|  |  |  | 	size_t len_utf8; | 
					
						
							|  |  |  | } g_vfont_clipboard = {NULL}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BKE_vfont_clipboard_free(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MEM_SAFE_FREE(g_vfont_clipboard.text_buffer); | 
					
						
							|  |  |  | 	MEM_SAFE_FREE(g_vfont_clipboard.info_buffer); | 
					
						
							|  |  |  | 	g_vfont_clipboard.len_wchar = 0; | 
					
						
							|  |  |  | 	g_vfont_clipboard.len_utf8 = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BKE_vfont_clipboard_set(const wchar_t *text_buf, const CharInfo *info_buf, const size_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	wchar_t *text; | 
					
						
							|  |  |  | 	CharInfo *info; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* clean previous buffers*/ | 
					
						
							|  |  |  | 	BKE_vfont_clipboard_free(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 	text = MEM_malloc_arrayN((len + 1), sizeof(wchar_t), __func__); | 
					
						
							| 
									
										
										
										
											2016-02-12 10:57:58 -02:00
										 |  |  | 	if (text == NULL) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 	info = MEM_malloc_arrayN(len, sizeof(CharInfo), __func__); | 
					
						
							| 
									
										
										
										
											2016-02-12 10:57:58 -02:00
										 |  |  | 	if (info == NULL) { | 
					
						
							|  |  |  | 		MEM_freeN(text); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(text, text_buf, len * sizeof(wchar_t)); | 
					
						
							|  |  |  | 	text[len] = '\0'; | 
					
						
							|  |  |  | 	memcpy(info, info_buf, len * sizeof(CharInfo)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* store new buffers */ | 
					
						
							|  |  |  | 	g_vfont_clipboard.text_buffer = text; | 
					
						
							|  |  |  | 	g_vfont_clipboard.info_buffer = info; | 
					
						
							|  |  |  | 	g_vfont_clipboard.len_utf8 = BLI_wstrlen_utf8(text); | 
					
						
							|  |  |  | 	g_vfont_clipboard.len_wchar = len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BKE_vfont_clipboard_get( | 
					
						
							|  |  |  |         wchar_t **r_text_buf, CharInfo **r_info_buf, | 
					
						
							|  |  |  |         size_t *r_len_utf8, size_t *r_len_wchar) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (r_text_buf) { | 
					
						
							|  |  |  | 		*r_text_buf = g_vfont_clipboard.text_buffer; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (r_info_buf) { | 
					
						
							|  |  |  | 		*r_info_buf = g_vfont_clipboard.info_buffer; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (r_len_wchar) { | 
					
						
							|  |  |  | 		*r_len_wchar = g_vfont_clipboard.len_wchar; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (r_len_utf8) { | 
					
						
							|  |  |  | 		*r_len_utf8 = g_vfont_clipboard.len_utf8; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ |