PageSourceSearch

https://renderdiagrams.org/lib/sceneObject_text.js?v=1.3

js renderdiagrams.org collected 2026-10-08 02:14:39 UTC 9,380 bytes, 393 lines download raw bytes

1// ----------------------------------------------------------------------------------------------------------------
2// Text
3// ----------------------------------------------------------------------------------------------------------------
4function Text(anchorPoint, initialText)
5{
6	this.scene				= null;
7	this.anchorPoint		= anchorPoint;
8	this.text				= "";
9	this.lines				= [];
10	this.halign				= 1;
11	this.valign				= 1;
12	this.angle				= 0;
13	this.lineSpacing		= 1.6;
14	this.font				= "Arial";
15	this.fontSize			= 1.0;
16	this.maxWidth			= 0;
17	this.totalHeight		= 0;
18	this.lineSizes			= [];
19	this.dimensionsStale	= true;
20	this.appearance			= new Appearance();
21	this.selected			= false;
22	this.visible			= true;
23	this.frozen				= false;
24	this.onChangeListeners	= [];
25	this.boundsMin			= new Vector(Number.MAX_VALUE,Number.MAX_VALUE);
26	this.boundsMax			= new Vector(-Number.MAX_VALUE,-Number.MAX_VALUE);
27
28	this.getBoundsMin = function()
29	{
30		return this.boundsMin;
31	}
32
33	this.getBoundsMax = function()
34	{
35		return this.boundsMax;
36	}
37
38	this.saveAsJavascript = function()
39	{
40		var str = "var text = new Text(";
41
42		str += "new Vector(" + this.anchorPoint.x + ", " + this.anchorPoint.y + ")";
43		str += ", unescape(\"" + escape(this.text) + "\")";
44		str += ");\n";
45
46		str += "text.halign = \"" + this.halign + "\";\n";
47		str += "text.valign = \"" + this.valign + "\";\n";
48		str += "text.font = \"" + this.font + "\";\n";
49		str += "text.fontSize = " + this.fontSize + ";\n";
50		str += this.appearance.saveAsJavascript("text");
51		str += "text.angle = " + this.angle + ";\n";
52		str += "text.lineSpacing = " + this.lineSpacing + ";\n";
53
54		str += "text.visible = " + this.visible + ";\n";
55		str += "text.frozen = " + this.frozen + ";\n";
56		str += "text.maxWidth = " + this.maxWidth + ";\n";
57		str += "text.totalHeight = " + this.totalHeight + ";\n";
58
59		if (this.name != undefined)
60		{
61			str += "text.name = \"" + this.name + "\";\n";
62		}
63
64		str += "scene.addObject(text);\n";
65		return str;
66	}
67
68	this.setText = function(s)
69	{
70		this.text = s;
71		this.lines = s.split("\n");
72		this.onChange();
73	}
74
75	this.addChangeListener = function(listener)
76	{
77		this.onChangeListeners.push(listener);
78	}
79
80	this.updateBounds = function()
81	{
82		this.boundsMin = new Vector(Number.MAX_VALUE,Number.MAX_VALUE);
83		this.boundsMax = new Vector(-Number.MAX_VALUE,-Number.MAX_VALUE);
84
85		var xAxis = rotate(new Vector(1, 0), this.angle * Math.PI / 180);
86		var yAxis = rotate(new Vector(0, 1), this.angle * Math.PI / 180);
87
88		var vMin = 0;
89		var vMax = 0;
90
91		if (this.valign == 0)
92		{
93			vMin = -this.totalHeight;
94			vMax = 0;
95		}
96		else if (this.valign == 1)
97		{
98			vMin = -this.totalHeight * 0.5;
99			vMax = this.totalHeight * 0.5;
100		}
101		else if (this.valign == 2)
102		{
103			vMin = 0;
104			vMax = this.totalHeight;
105		}
106
107		var hMin = 0;
108		var hMax = 0;
109
110		if (this.halign == 0)
111		{
112			hMin = 0;
113			hMax = this.maxWidth;
114		}
115		else if (this.halign == 1)
116		{
117			hMin = -this.maxWidth * 0.5;
118			hMax = this.maxWidth * 0.5;
119		}
120		else if (this.halign == 2)
121		{
122			hMin = -this.maxWidth;
123			hMax = 0;
124		}
125
126		var corners = [ mad(yAxis, vMin, mad(xAxis, hMin, this.anchorPoint)),
127						mad(yAxis, vMin, mad(xAxis, hMax, this.anchorPoint)),
128						mad(yAxis, vMax, mad(xAxis, hMin, this.anchorPoint)),
129						mad(yAxis, vMax, mad(xAxis, hMax, this.anchorPoint)) ];
130
131		for (var i=0; i!=corners.length; ++i)
132		{
133			this.boundsMin = min(this.boundsMin, corners[i]);
134			this.boundsMax = max(this.boundsMax, corners[i]);
135		}
136	}
137
138	this.onChange = function(changeDetails)
139	{
140		// Backwards compatibility
141		this.appearance.SetFromOldProperties(this);
142
143		this.dimensionsStale = true;
144
145		this.updateBounds();
146
147		for (var i=0; i!=this.onChangeListeners.length; ++i)
148		{
149			this.onChangeListeners[i](this, changeDetails);
150		}
151	}
152	
153	this.draw = function(camera)
154	{
155		var fontSize = camera.scale(this.fontSize);
156		var font = fontSize + "px " + this.font;
157
158		if (this.dimensionsStale)
159		{
160			this.maxWidth = 0;
161			this.totalHeight = 0;
162			this.lineSizes = new Array(this.lines.length);
163
164			for (var i=0; i!=this.lines.length; ++i)
165			{
166				var lineSize = camera.measureText(this.lines[i], font);
167			
168				this.lineSizes[i] = lineSize;
169				this.maxWidth = Math.max(this.maxWidth, lineSize.x);
170				this.totalHeight += lineSize.y * this.lineSpacing;
171			}
172
173			this.dimensionsStale = false;
174		}
175
176		this.updateBounds();
177
178		var xAxis = rotate(new Vector(1, 0), this.angle * Math.PI / 180);
179		var yAxis = rotate(new Vector(0, 1), this.angle * Math.PI / 180);
180
181		if (this.selected)
182		{
183			camera.drawLine(this.anchorPoint, mad(xAxis, this.maxWidth, this.anchorPoint), this.appearance.GetLineColor(), 1, [3, 3]);
184		}
185
186		var vOffset = 0;
187
188		if (this.valign == 0)
189		{
190			vOffset = 0;
191		}
192		else if (this.valign == 1)
193		{
194			vOffset = this.totalHeight * 0.5;
195		}
196		else if (this.valign == 2)
197		{
198			vOffset = this.totalHeight;
199		}
200
201		for (var i=0; i!=this.lines.length; ++i)
202		{
203			var lineSize = this.lineSizes[i];
204			var hOffset = 0;
205
206			if (this.halign == 0)
207			{
208				hOffset = 0;
209			}
210			else if (this.halign == 1)
211			{
212				hOffset = -lineSize.x * 0.5;
213			}
214			else if (this.halign == 2)
215			{
216				hOffset = -lineSize.x;
217			}
218
219			vOffset += -lineSize.y * this.lineSpacing;
220
221			var p = mad(yAxis, vOffset, mad(xAxis, hOffset, this.anchorPoint));
222
223			camera.drawText(p, this.lines[i], this.appearance.GetLineColor(), "left", this.angle * Math.PI / 180, font);
224		}
225	}
226	
227	this.hitTest = function(a, b, camera)
228	{
229		var xAxis = rotate(new Vector(1, 0), this.angle * Math.PI / 180);
230		var yAxis = rotate(new Vector(0, 1), this.angle * Math.PI / 180);
231
232		var hMin = 0;
233		var hMax = 0;
234
235		if (this.halign == 0)
236		{
237			hMin = 0;
238			hMax = this.maxWidth;
239		}
240		else if (this.halign == 1)
241		{
242			hMin = -this.maxWidth * 0.5;
243			hMax = this.maxWidth * 0.5;
244		}
245		else if (this.halign == 2)
246		{
247			hMin = -this.maxWidth;
248			hMax = 0;
249		}
250
251		var vOffset = 0;
252
253		if (this.valign == 0)
254		{
255			vOffset = 0;
256		}
257		else if (this.valign == 1)
258		{
259			vOffset = this.totalHeight * 0.5;
260		}
261		else if (this.valign == 2)
262		{
263			vOffset = this.totalHeight;
264		}
265
266		var lineHeight = this.totalHeight / this.lines.length;
267
268		vOffset += lineHeight * 0.5;
269		
270		for (var i=0; i!=this.lines.length; ++i)
271		{
272			vOffset += -lineHeight;
273
274			if (overlapRectLine(a, b, mad(yAxis, vOffset, mad(xAxis, hMin, this.anchorPoint)), mad(yAxis, vOffset, mad(xAxis, hMax, this.anchorPoint))))
275			{
276				return true;
277			}
278		}
279
280
281		return false;
282	}
283
284	this.getSnapPoints = function ()
285	{
286		var points = [	{ type: "center", p: this.anchorPoint } ];
287		return points;
288	}
289
290	this.getDragPoints = function(localSpace, camera)
291	{
292		if (this.isFrozen())
293			return [];
294
295		var xAxis = rotate(new Vector(1, 0), this.angle * Math.PI / 180);
296		var yAxis = rotate(new Vector(0, 1), this.angle * Math.PI / 180);
297
298		var points = [ this.anchorPoint, mad(xAxis, this.maxWidth, this.anchorPoint) ];
299
300		return points;
301	}
302
303	this.drawDragPoint = function(camera, index, position, localSpace, alpha)
304	{
305		if (alpha == undefined)
306			alpha = 1;
307
308		var points = this.getDragPoints(localSpace, camera);
309
310		camera.drawRectangle(points[index], camera.invScale(10), "rgba(255,0,0," + alpha + ")", 2);
311	}
312
313	this.setDragPointPos = function(index, p, localSpace, dragStartPoint, camera)
314	{
315		if (index == 0)
316		{
317			this.anchorPoint = p;
318		}
319		else
320		{
321			this.angle = toAngle(sub(p, this.anchorPoint)) * 180 / Math.PI;
322		}
323
324		this.onChange();
325	}
326
327	this.getOrigin = function()
328	{
329		return this.anchorPoint;
330	}
331	
332	this.setOrigin = function(p)
333	{
334		this.anchorPoint = p;
335		this.onChange();
336	}
337
338	this.getProperties = function()
339	{
340		var appearanceControl = new PopoutContainer(undefined, "images/color_wheel.svg");
341		{
342			appearanceControl.addControl("", new AppearanceControl(this.appearance, true, false, function(){ this.onChange(); }.bind(this)) );
343		}
344
345		return	[
346					{name: "Appearance", control:appearanceControl },
347					{name: "Text", control: new PopoutTextBox(this.text, "multi", true, 0, function (value) { this.setText(value); this.onChange(); }.bind(this)) },
348					{name: "Font", control:new TextBox(this.font, true, false, 32, function(value){ this.font = value; this.onChange(); }.bind(this) )},
349					{name: "Font Size", control: new PopoutSlider(0.1, 5.0, this.fontSize, 0.1, function (value) { this.fontSize = value; this.onChange(); }.bind(this)) },
350					{name: "Line Spacing", control: new PopoutSlider(0.1, 5.0, this.lineSpacing, 0.1, function (value) { this.lineSpacing = value; this.onChange(); }.bind(this)) },
351					{name: "H Align", control: new Dropdown(["left", "center", "right"], this.halign, function (value) { this.halign = value; this.onChange(); }.bind(this) )},
352					{name: "V Align", control: new Dropdown(["top", "center", "bottom"], this.valign, function (value) { this.valign = value; this.onChange(); }.bind(this) )},
353				];
354	}
355
356	this.toggleVisibility = function(v)
357	{
358		var newVisible = (v!==undefined) ? v : !this.visible;
359		if (this.visible != newVisible)
360		{
361			this.visible = newVisible;
362			this.onChange();
363		}
364	}
365
366	this.isVisible = function()
367	{
368		return this.visible;
369	}
370
371	this.toggleFrozen = function(f)
372	{
373		this.frozen = (f!==undefined) ? f : !this.frozen;
374		this.onChange();
375	}
376
377	this.isFrozen = function()
378	{
379		return this.frozen;
380	}
381
382	this.setSelected = function(selected)
383	{
384		this.selected = selected;
385	}
386
387	this.isSelected = function()
388	{
389		return this.selected;
390	}
391
392	this.setText(initialText);
393}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.