From fe088fcfe2e0ca4b2fef755d3f1a11823f2fb220 Mon Sep 17 00:00:00 2001
From: Rudolf Polzer <divverent@alientrap.org>
Date: Wed, 23 Jun 2010 15:01:42 +0200
Subject: [PATCH] menu: fix lots of issues with font rendering

---
 qcsrc/menu/draw.qc                |  11 ++-
 qcsrc/menu/item/container.c       | 112 +++++++++++++++++++++++-------
 qcsrc/menu/item/label.c           |  12 +++-
 qcsrc/menu/item/modalcontroller.c |  11 ++-
 qcsrc/menu/item/nexposee.c        |  11 ++-
 5 files changed, 121 insertions(+), 36 deletions(-)

diff --git a/qcsrc/menu/draw.qc b/qcsrc/menu/draw.qc
index 2cbf3694d6..9e722cb12a 100644
--- a/qcsrc/menu/draw.qc
+++ b/qcsrc/menu/draw.qc
@@ -230,9 +230,15 @@ void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector the
 }
 void draw_Text(vector theOrigin, string theText, vector theSize, vector theColor, float theAlpha, float ICanHasKallerz)
 {
-	vector fs;
 	if(theSize_x <= 0 || theSize_y <= 0)
 		error("Drawing zero size text?\n");
+
+	/*
+	float wi;
+	wi = draw_TextWidth(theText, ICanHasKallerz, theSize);
+	draw_Fill(theOrigin, '1 0 0' * wi + '0 1 0' * theSize_y, '1 0 0', 0.3);
+	*/
+
 	if(ICanHasKallerz)
 		drawcolorcodedstring(boxToGlobal(theOrigin, draw_shift, draw_scale), theText, globalToBoxSize(boxToGlobalSize(theSize, draw_scale), draw_fontscale), theAlpha * draw_alpha, 0);
 	else
@@ -248,11 +254,10 @@ float draw_TextWidth(string theText, float ICanHasKallerz, vector SizeThxBye)
 {
 	//return strlen(theText);
 	//print("draw_TextWidth \"", theText, "\"\n");
-	vector fs;
 	vector v;
 	v = '0 0 0';
 	//float r;
-	v_x = stringwidth(theText, ICanHasKallerz, boxToGlobalSize(SizeThxBye, draw_scale)) / draw_fontscale_x;
+	v_x = stringwidth(theText, ICanHasKallerz, boxToGlobalSize(SizeThxBye, draw_scale));
 	v = globalToBoxSize(v, draw_scale);
 	return v_x;
 }
diff --git a/qcsrc/menu/item/container.c b/qcsrc/menu/item/container.c
index b29eea0b80..d10e6a486d 100644
--- a/qcsrc/menu/item/container.c
+++ b/qcsrc/menu/item/container.c
@@ -9,7 +9,7 @@ CLASS(Container) EXTENDS(Item)
 	METHOD(Container, mouseRelease, float(entity, vector))
 	METHOD(Container, focusLeave, void(entity))
 	METHOD(Container, resizeNotify, void(entity, vector, vector, vector, vector))
-	METHOD(Container, resizeNotifyLie, void(entity, vector, vector, vector, vector, .vector, .vector))
+	METHOD(Container, resizeNotifyLie, void(entity, vector, vector, vector, vector, .vector, .vector, .vector))
 	METHOD(Container, addItem, void(entity, entity, vector, vector, float))
 	METHOD(Container, addItemCentered, void(entity, entity, vector, float))
 	METHOD(Container, moveItemAfter, void(entity, entity, entity))
@@ -25,6 +25,10 @@ CLASS(Container) EXTENDS(Item)
 	ATTRIB(Container, lastChild, entity, NULL)
 	ATTRIB(Container, focusedChild, entity, NULL)
 	ATTRIB(Container, shown, float, 0)
+
+	METHOD(Container, enterSubitem, void(entity, entity))
+	METHOD(Container, enterLieSubitem, void(entity, vector, vector, vector, float))
+	METHOD(Container, leaveSubitem, void(entity))
 ENDCLASS(Container)
 .entity nextSibling;
 .entity prevSibling;
@@ -33,9 +37,40 @@ ENDCLASS(Container)
 .vector Container_size;
 .vector Container_fontscale;
 .float Container_alpha;
+.vector Container_save_shift;
+.vector Container_save_scale;
+.vector Container_save_fontscale;
+.float Container_save_alpha;
 #endif
 
 #ifdef IMPLEMENTATION
+void Container_enterSubitem(entity me, entity sub)
+{
+	me.enterLieSubitem(me, sub.Container_origin, sub.Container_size, sub.Container_fontscale, sub.Container_alpha);
+}
+
+void Container_enterLieSubitem(entity me, vector o, vector s, vector f, float a)
+{
+	me.Container_save_shift = draw_shift;
+	me.Container_save_scale = draw_scale;
+	me.Container_save_alpha = draw_alpha;
+	me.Container_save_fontscale = draw_fontscale;
+
+	draw_shift = boxToGlobal(o, draw_shift, draw_scale);
+	draw_scale = boxToGlobalSize(s, draw_scale);
+	if(f != '0 0 0')
+		draw_fontscale = boxToGlobalSize(f, draw_fontscale);
+	draw_alpha *= a;
+}
+
+void Container_leaveSubitem(entity me)
+{
+	draw_shift = me.Container_save_shift;
+	draw_scale = me.Container_save_scale;
+	draw_alpha = me.Container_save_alpha;
+	draw_fontscale = me.Container_save_fontscale;
+}
+
 void Container_showNotify(entity me)
 {
 	entity e;
@@ -73,7 +108,7 @@ void Container_setAlphaOf(entity me, entity other, float theAlpha)
 	other.Container_alpha = theAlpha;
 }
 
-void Container_resizeNotifyLie(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize, .vector originField, .vector sizeField)
+void Container_resizeNotifyLie(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize, .vector originField, .vector sizeField, .vector fontScaleField)
 {
 	entity e;
 	vector o, s;
@@ -82,7 +117,9 @@ void Container_resizeNotifyLie(entity me, vector relOrigin, vector relSize, vect
 	{
 		o = e.originField;
 		s = e.sizeField;
+		me.enterLieSubitem(me, o, s, e.fontScaleField, e.Container_alpha);
 		e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize));
+		me.leaveSubitem(me);
 	}
 	do
 	{
@@ -94,7 +131,9 @@ void Container_resizeNotifyLie(entity me, vector relOrigin, vector relSize, vect
 				d = 1;
 				o = e.originField;
 				s = e.sizeField;
+				me.enterLieSubitem(me, o, s, e.fontScaleField, e.Container_alpha);
 				e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize));
+				me.leaveSubitem(me);
 			}
 	}
 	while(d);
@@ -103,7 +142,7 @@ void Container_resizeNotifyLie(entity me, vector relOrigin, vector relSize, vect
 
 void Container_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 {
-	me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Container_origin, Container_size);
+	me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Container_origin, Container_size, Container_fontscale);
 }
 
 entity Container_itemFromPoint(entity me, vector pos)
@@ -125,16 +164,8 @@ entity Container_itemFromPoint(entity me, vector pos)
 
 void Container_draw(entity me)
 {
-	vector oldshift;
-	vector oldscale;
-	float oldalpha;
-	vector oldfontscale;
 	entity e;
 
-	oldshift = draw_shift;
-	oldscale = draw_scale;
-	oldalpha = draw_alpha;
-	oldfontscale = draw_fontscale;
 	me.focusable = 0;
 	for(e = me.firstChild; e; e = e.nextSibling)
 	{
@@ -142,16 +173,9 @@ void Container_draw(entity me)
 			me.focusable += 1;
 		if(e.Container_alpha < 0.003) // can't change color values anyway
 			continue;
-		draw_shift = boxToGlobal(e.Container_origin, oldshift, oldscale);
-		draw_scale = boxToGlobalSize(e.Container_size, oldscale);
-		if(e.Container_fontscale != '0 0 0')
-			draw_fontscale = boxToGlobalSize(e.Container_fontscale, oldfontscale);
-		draw_alpha *= e.Container_alpha;
+		me.enterSubitem(me, e);
 		e.draw(e);
-		draw_shift = oldshift;
-		draw_scale = oldscale;
-		draw_fontscale = oldfontscale;
-		draw_alpha = oldalpha;
+		me.leaveSubitem(me);
 	}
 };
 
@@ -163,51 +187,87 @@ void Container_focusLeave(entity me)
 float Container_keyUp(entity me, float scan, float ascii, float shift)
 {
 	entity f;
+	float r;
 	f = me.focusedChild;
 	if(f)
-		return f.keyUp(f, scan, ascii, shift);
+	{
+		me.enterSubitem(me, f);
+		r = f.keyUp(f, scan, ascii, shift);
+		me.leaveSubitem(me);
+		return r;
+	}
 	return 0;
 }
 
 float Container_keyDown(entity me, float scan, float ascii, float shift)
 {
 	entity f;
+	float r;
 	f = me.focusedChild;
 	if(f)
-		return f.keyDown(f, scan, ascii, shift);
+	{
+		me.enterSubitem(me, f);
+		r = f.keyDown(f, scan, ascii, shift);
+		me.leaveSubitem(me);
+		return r;
+	}
 	return 0;
 }
 
 float Container_mouseMove(entity me, vector pos)
 {
 	entity f;
+	float r;
 	f = me.focusedChild;
 	if(f)
-		return f.mouseMove(f, globalToBox(pos, f.Container_origin, f.Container_size));
+	{
+		me.enterSubitem(me, f);
+		r = f.mouseMove(f, globalToBox(pos, f.Container_origin, f.Container_size));
+		me.leaveSubitem(me);
+		return r;
+	}
 	return 0;
 }
 float Container_mousePress(entity me, vector pos)
 {
 	entity f;
+	float r;
 	f = me.focusedChild;
 	if(f)
-		return f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size));
+	{
+		me.enterSubitem(me, f);
+		r = f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size));
+		me.leaveSubitem(me);
+		return r;
+	}
 	return 0;
 }
 float Container_mouseDrag(entity me, vector pos)
 {
 	entity f;
+	float r;
 	f = me.focusedChild;
 	if(f)
-		return f.mouseDrag(f, globalToBox(pos, f.Container_origin, f.Container_size));
+	{
+		me.enterSubitem(me, f);
+		r = f.mouseDrag(f, globalToBox(pos, f.Container_origin, f.Container_size));
+		me.leaveSubitem(me);
+		return r;
+	}
 	return 0;
 }
 float Container_mouseRelease(entity me, vector pos)
 {
 	entity f;
+	float r;
 	f = me.focusedChild;
 	if(f)
-		return f.mouseRelease(f, globalToBox(pos, f.Container_origin, f.Container_size));
+	{
+		me.enterSubitem(me, f);
+		r = f.mouseRelease(f, globalToBox(pos, f.Container_origin, f.Container_size));
+		me.leaveSubitem(me);
+		return r;
+	}
 	return 0;
 }
 
diff --git a/qcsrc/menu/item/label.c b/qcsrc/menu/item/label.c
index 5a6bb1c697..67db22a1b4 100644
--- a/qcsrc/menu/item/label.c
+++ b/qcsrc/menu/item/label.c
@@ -22,6 +22,7 @@ CLASS(Label) EXTENDS(Item)
 	ATTRIB(Label, disabledAlpha, float, 0.3)
 	ATTRIB(Label, textEntity, entity, NULL)
 	ATTRIB(Label, allowWrap, float, 0)
+	ATTRIB(Label, recalcPos, float, 0)
 ENDCLASS(Label)
 #endif
 
@@ -33,7 +34,7 @@ string Label_toString(entity me)
 void Label_setText(entity me, string txt)
 {
 	me.text = txt;
-	me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(draw_TextWidth(me.text, me.allowColors, me.realFontSize), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
+	me.recalcPos = 1;
 }
 void Label_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 {
@@ -45,8 +46,9 @@ void Label_resizeNotify(entity me, vector relOrigin, vector relSize, vector absO
 		me.keepspaceLeft = me.marginLeft * me.realFontSize_x;
 	if(me.marginRight)
 		me.keepspaceRight = me.marginRight * me.realFontSize_x;
-	me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(draw_TextWidth(me.text, me.allowColors, me.realFontSize), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
 	me.realOrigin_y = 0.5 * (1 - me.realFontSize_y);
+	me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(draw_TextWidth(me.text, me.allowColors, me.realFontSize), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
+	me.recalcPos = 0;
 }
 void Label_configureLabel(entity me, string txt, float sz, float algn)
 {
@@ -64,10 +66,14 @@ void Label_draw(entity me)
 	if(me.textEntity)
 	{
 		t = me.textEntity.toString(me.textEntity);
-		me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(draw_TextWidth(t, 0, me.realFontSize), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
+		me.recalcPos = 1;
 	}
 	else
 		t = me.text;
+
+	if(me.recalcPos)
+		me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(draw_TextWidth(t, me.allowColors, me.realFontSize), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
+	me.recalcPos = 0;
 	
 	if(me.fontSize)
 		if(t)
diff --git a/qcsrc/menu/item/modalcontroller.c b/qcsrc/menu/item/modalcontroller.c
index 4bc2fb9bde..82bd6f62b8 100644
--- a/qcsrc/menu/item/modalcontroller.c
+++ b/qcsrc/menu/item/modalcontroller.c
@@ -52,6 +52,7 @@ void DialogCloseButton_Click(entity button, entity tab); // assumes a button has
 
 .vector ModalController_initialSize;
 .vector ModalController_initialOrigin;
+.vector ModalController_initialFontScale;
 .float ModalController_initialAlpha;
 .vector ModalController_buttonSize;
 .vector ModalController_buttonOrigin;
@@ -97,7 +98,7 @@ void DialogCloseButton_Click(entity button, entity tab)
 
 void ModalController_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 {
-	me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, ModalController_initialOrigin, ModalController_initialSize);
+	me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, ModalController_initialOrigin, ModalController_initialSize, ModalController_initialFontScale);
 }
 
 void ModalController_switchState(entity me, entity other, float state, float skipAnimation)
@@ -140,6 +141,7 @@ void ModalController_draw(entity me)
 	float df; // animation step size
 	float prevFactor, targetFactor;
 	vector targetOrigin, targetSize; float targetAlpha;
+	vector fs;
 	animating = 0;
 
 	for(e = me.firstChild; e; e = e.nextSibling)
@@ -216,7 +218,9 @@ void ModalController_draw(entity me)
 		// --> (maxima)
 		// o' = (to * (f - f_prev) + o * (1 - f)) / (1 - f_prev)
 
-		e.Container_fontscale = globalToBoxSize(e.Container_size, e.ModalController_initialSize);
+		fs = globalToBoxSize(e.Container_size, e.ModalController_initialSize);
+		e.Container_fontscale_x = fs_x * e.ModalController_initialFontScale_x;
+		e.Container_fontscale_y = fs_y * e.ModalController_initialFontScale_y;
 	}
 	if(animating || !me.focused)
 		me.setFocus(me, NULL);
@@ -242,9 +246,12 @@ void ModalController_addTab(entity me, entity other, entity tabButton)
 void ModalController_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
 {
 	SUPER(ModalController).addItem(me, other, theOrigin, theSize, (other == me.firstChild) ? theAlpha : 0);
+	other.ModalController_initialFontScale = other.Container_fontscale;
 	other.ModalController_initialSize = other.Container_size;
 	other.ModalController_initialOrigin = other.Container_origin;
 	other.ModalController_initialAlpha = theAlpha; // hope Container never modifies this
+	if(other.ModalController_initialFontScale == '0 0 0')
+		other.ModalController_initialFontScale = '1 1 0';
 }
 
 void ModalController_showChild(entity me, entity other, vector theOrigin, vector theSize, float skipAnimation)
diff --git a/qcsrc/menu/item/nexposee.c b/qcsrc/menu/item/nexposee.c
index c9232b192d..c43f44f509 100644
--- a/qcsrc/menu/item/nexposee.c
+++ b/qcsrc/menu/item/nexposee.c
@@ -35,6 +35,7 @@ void ExposeeCloseButton_Click(entity button, entity other); // un-exposees the c
 #ifdef IMPLEMENTATION
 
 .vector Nexposee_initialSize;
+.vector Nexposee_initialFontScale;
 .vector Nexposee_initialOrigin;
 .float Nexposee_initialAlpha;
 
@@ -61,7 +62,7 @@ void ExposeeCloseButton_Click(entity button, entity other)
 void Nexposee_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 {
 	me.calc(me);
-	me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Nexposee_initialOrigin, Nexposee_initialSize);
+	me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Nexposee_initialOrigin, Nexposee_initialSize, Nexposee_initialFontScale);
 }
 
 void Nexposee_Calc_Scale(entity me, float scale)
@@ -141,6 +142,7 @@ void Nexposee_draw(entity me)
 	float a0;
 	entity e;
 	float f;
+	vector fs;
 
 	if(me.animationState == -1)
 	{
@@ -203,7 +205,9 @@ void Nexposee_draw(entity me)
 		}
 		me.setAlphaOf(me, e, e.Container_alpha * (1 - f) + a * f);
 
-		e.Container_fontscale = globalToBoxSize(e.Container_size, e.Nexposee_initialSize);
+		fs = globalToBoxSize(e.Container_size, e.Nexposee_initialSize);
+		e.Container_fontscale_x = fs_x * e.Nexposee_initialFontScale_x;
+		e.Container_fontscale_y = fs_y * e.Nexposee_initialFontScale_y;
 	}
 
 	SUPER(Nexposee).draw(me);
@@ -338,9 +342,12 @@ float Nexposee_keyDown(entity me, float scan, float ascii, float shift)
 void Nexposee_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
 {
 	SUPER(Nexposee).addItem(me, other, theOrigin, theSize, theAlpha);
+	other.Nexposee_initialFontScale = other.Container_fontscale;
 	other.Nexposee_initialSize = other.Container_size;
 	other.Nexposee_initialOrigin = other.Container_origin;
 	other.Nexposee_initialAlpha = other.Container_alpha;
+	if(other.Nexposee_initialFontScale == '0 0 0')
+		other.Nexposee_initialFontScale = '1 1 0';
 }
 
 void Nexposee_focusEnter(entity me)
-- 
2.39.5