diff options
| author | Richard Linden <none@none> | 2010-07-27 10:30:17 -0700 | 
|---|---|---|
| committer | Richard Linden <none@none> | 2010-07-27 10:30:17 -0700 | 
| commit | b4dfa76c9de73c6bebf54d6112b699a1e654ba63 (patch) | |
| tree | 72a2fcddec5d08ce9db9b97984b884bb0943e19f | |
| parent | c8316be258cdf9252c2d1bec0f223bc4245ff205 (diff) | |
| parent | 50d8cc6d377b90b27c57b390eb6626223a1685a7 (diff) | |
merge
| -rw-r--r-- | indra/llrender/llfontfreetype.cpp | 6 | ||||
| -rw-r--r-- | indra/llrender/llfontfreetype.h | 4 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.cpp | 195 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.h | 4 | ||||
| -rw-r--r-- | indra/llrender/llrender.cpp | 97 | ||||
| -rw-r--r-- | indra/llrender/llrender.h | 8 | ||||
| -rw-r--r-- | indra/llui/lllocalcliprect.cpp | 42 | ||||
| -rw-r--r-- | indra/llui/lllocalcliprect.h | 26 | ||||
| -rw-r--r-- | indra/llui/lltextbase.cpp | 17 | 
9 files changed, 243 insertions, 156 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index a86bbbffff..0a16b5120a 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -259,10 +259,10 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const  	}  	else  	{ -		gi = get_if_there(mCharGlyphInfoMap, (llwchar)0, (LLFontGlyphInfo*)NULL); -		if (gi) +		char_glyph_info_map_t::iterator found_it = mCharGlyphInfoMap.find((llwchar)0); +		if (found_it != mCharGlyphInfoMap.end())  		{ -			return gi->mXAdvance; +			return found_it->second->mXAdvance;  		}  	} diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index f60d09316d..4b4a0bb189 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -33,7 +33,7 @@  #ifndef LL_LLFONTFREETYPE_H  #define LL_LLFONTFREETYPE_H -#include <map> +#include <boost/unordered_map.hpp>  #include "llpointer.h"  #include "llstl.h" @@ -170,7 +170,7 @@ private:  	BOOL mValid; -	typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t; +	typedef boost::unordered_map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;  	mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap  	mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 6eb5e0eff4..c0297eae3e 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -181,12 +181,17 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  	gGL.loadUIIdentity(); -	gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ); +	//gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ);  	// this code snaps the text origin to a pixel grid to start with -	F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX); -	F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY); -	gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f); +	//F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX); +	//F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY); +	//gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f); + +	LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY)); +	// snap the text origin to a pixel grid to start with +	origin.mV[VX] -= llround((F32)sCurOrigin.mX) - (sCurOrigin.mX); +	origin.mV[VY] -= llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);  	LLFastTimer t(FTM_RENDER_FONTS); @@ -210,8 +215,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons   	// Not guaranteed to be set correctly  	gGL.setSceneBlendType(LLRender::BT_ALPHA); -	cur_x = ((F32)x * sScaleX); -	cur_y = ((F32)y * sScaleY); +	cur_x = ((F32)x * sScaleX) + origin.mV[VX]; +	cur_y = ((F32)y * sScaleY) + origin.mV[VY];  	// Offset y by vertical alignment.  	switch (valign) @@ -276,6 +281,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  	const LLFontGlyphInfo* next_glyph = NULL; +	const S32 GLYPH_BATCH_SIZE = 30; +	LLVector3 vertices[GLYPH_BATCH_SIZE * 4]; +	LLVector2 uvs[GLYPH_BATCH_SIZE * 4]; +	LLColor4U colors[GLYPH_BATCH_SIZE * 4]; + +	S32 glyph_count = 0;  	for (i = begin_offset; i < begin_offset + length; i++)  	{  		llwchar wch = wstr[i]; @@ -313,7 +324,18 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  				    llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,  				    llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); -		drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength); +		if (glyph_count >= GLYPH_BATCH_SIZE) +		{ +			gGL.begin(LLRender::QUADS); +			{ +				gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); +			} +			gGL.end(); + +			glyph_count = 0; +		} + +		drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength);  		chars_drawn++;  		cur_x += fgi->mXAdvance; @@ -338,11 +360,19 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  		cur_render_y = cur_y;  	} +	gGL.begin(LLRender::QUADS); +	{ +		gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); +	} +	gGL.end(); + +  	if (right_x)  	{  		*right_x = cur_x / sScaleX;  	} +	//FIXME: add underline as glyph?  	if (style_to_add & UNDERLINE)  	{  		F32 descender = mFontFreetype->getDescenderHeight(); @@ -1091,95 +1121,96 @@ LLFontGL &LLFontGL::operator=(const LLFontGL &source)  	return *this;  } -void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const +void LLFontGL::renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const  { -	gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); -	gGL.vertex2f(llfont_round_x(screen_rect.mRight),  -				llfont_round_y(screen_rect.mTop)); - -	gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); -	gGL.vertex2f(llfont_round_x(screen_rect.mLeft),  -				llfont_round_y(screen_rect.mTop)); - -	gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); -	gGL.vertex2f(llfont_round_x(screen_rect.mLeft + slant_amt),  -				llfont_round_y(screen_rect.mBottom)); - -	gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); -	gGL.vertex2f(llfont_round_x(screen_rect.mRight + slant_amt),  -				llfont_round_y(screen_rect.mBottom)); +	S32 index = 0; + +	vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mTop), 0.f); +	uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); +	colors_out[index] = color; +	index++; + +	vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mTop), 0.f); +	uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); +	colors_out[index] = color; +	index++; + +	vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mBottom), 0.f); +	uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); +	colors_out[index] = color; +	index++; + +	vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mBottom), 0.f); +	uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); +	colors_out[index] = color;  } -void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const +//FIXME: do colors out as well +void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const  {  	F32 slant_offset;  	slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f); -	gGL.begin(LLRender::QUADS); +	//FIXME: bold and drop shadow are mutually exclusive only for convenience +	//Allow both when we need them. +	if (style & BOLD)  	{ -		//FIXME: bold and drop shadow are mutually exclusive only for convenience -		//Allow both when we need them. -		if (style & BOLD) +		for (S32 pass = 0; pass < 2; pass++)  		{ -			gGL.color4fv(color.mV); -			for (S32 pass = 0; pass < 2; pass++) -			{ -				LLRectf screen_rect_offset = screen_rect; +			LLRectf screen_rect_offset = screen_rect; -				screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f); -				renderQuad(screen_rect_offset, uv_rect, slant_offset); -			} +			screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f); +			renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, color, slant_offset); +			glyph_count++;  		} -		else if (shadow == DROP_SHADOW_SOFT) +	} +	else if (shadow == DROP_SHADOW_SOFT) +	{ +		LLColor4U shadow_color = LLFontGL::sShadowColor; +		shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH; +		for (S32 pass = 0; pass < 5; pass++)  		{ -			LLColor4 shadow_color = LLFontGL::sShadowColor; -			shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH; -			gGL.color4fv(shadow_color.mV); -			for (S32 pass = 0; pass < 5; pass++) -			{ -				LLRectf screen_rect_offset = screen_rect; +			LLRectf screen_rect_offset = screen_rect; -				switch(pass) -				{ -				case 0: -					screen_rect_offset.translate(-1.f, -1.f); -					break; -				case 1: -					screen_rect_offset.translate(1.f, -1.f); -					break; -				case 2: -					screen_rect_offset.translate(1.f, 1.f); -					break; -				case 3: -					screen_rect_offset.translate(-1.f, 1.f); -					break; -				case 4: -					screen_rect_offset.translate(0, -2.f); -					break; -				} -			 -				renderQuad(screen_rect_offset, uv_rect, slant_offset); +			switch(pass) +			{ +			case 0: +				screen_rect_offset.translate(-1.f, -1.f); +				break; +			case 1: +				screen_rect_offset.translate(1.f, -1.f); +				break; +			case 2: +				screen_rect_offset.translate(1.f, 1.f); +				break; +			case 3: +				screen_rect_offset.translate(-1.f, 1.f); +				break; +			case 4: +				screen_rect_offset.translate(0, -2.f); +				break;  			} -			gGL.color4fv(color.mV); -			renderQuad(screen_rect, uv_rect, slant_offset); -		} -		else if (shadow == DROP_SHADOW) -		{ -			LLColor4 shadow_color = LLFontGL::sShadowColor; -			shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength; -			gGL.color4fv(shadow_color.mV); -			LLRectf screen_rect_shadow = screen_rect; -			screen_rect_shadow.translate(1.f, -1.f); -			renderQuad(screen_rect_shadow, uv_rect, slant_offset); -			gGL.color4fv(color.mV); -			renderQuad(screen_rect, uv_rect, slant_offset); -		} -		else // normal rendering -		{ -			gGL.color4fv(color.mV); -			renderQuad(screen_rect, uv_rect, slant_offset); +		 +			renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, shadow_color, slant_offset); +			glyph_count++;  		} - +		renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset); +		glyph_count++; +	} +	else if (shadow == DROP_SHADOW) +	{ +		LLColor4 shadow_color = LLFontGL::sShadowColor; +		shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength; +		LLRectf screen_rect_shadow = screen_rect; +		screen_rect_shadow.translate(1.f, -1.f); +		renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_shadow, uv_rect, shadow_color, slant_offset); +		glyph_count++; +		renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset); +		glyph_count++; +	} +	else // normal rendering +	{ +		renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset); +		glyph_count++;  	} -	gGL.end();  } diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index f29ac5165c..8bc45fbf74 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -217,8 +217,8 @@ private:  	LLFontDescriptor mFontDescriptor;  	LLPointer<LLFontFreetype> mFontFreetype; -	void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const; -	void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; +	void renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const; +	void drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;  	// Registry holds all instantiated fonts.  	static LLFontRegistry* sFontRegistry; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 5597b23c69..64238b2008 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -851,9 +851,9 @@ void LLRender::translateUI(F32 x, F32 y, F32 z)  		llerrs << "Need to push a UI translation frame before offsetting" << llendl;  	} -	mUIOffset.front().mV[0] += x; -	mUIOffset.front().mV[1] += y; -	mUIOffset.front().mV[2] += z; +	mUIOffset.back().mV[0] += x; +	mUIOffset.back().mV[1] += y; +	mUIOffset.back().mV[2] += z;  }  void LLRender::scaleUI(F32 x, F32 y, F32 z) @@ -863,27 +863,27 @@ void LLRender::scaleUI(F32 x, F32 y, F32 z)  		llerrs << "Need to push a UI transformation frame before scaling." << llendl;  	} -	mUIScale.front().scaleVec(LLVector3(x,y,z)); +	mUIScale.back().scaleVec(LLVector3(x,y,z));  }  void LLRender::pushUIMatrix()  {  	if (mUIOffset.empty())  	{ -		mUIOffset.push_front(LLVector3(0,0,0)); +		mUIOffset.push_back(LLVector3(0,0,0));  	}  	else  	{ -		mUIOffset.push_front(mUIOffset.front()); +		mUIOffset.push_back(mUIOffset.back());  	}  	if (mUIScale.empty())  	{ -		mUIScale.push_front(LLVector3(1,1,1)); +		mUIScale.push_back(LLVector3(1,1,1));  	}  	else  	{ -		mUIScale.push_front(mUIScale.front()); +		mUIScale.push_back(mUIScale.back());  	}  } @@ -893,8 +893,8 @@ void LLRender::popUIMatrix()  	{  		llerrs << "UI offset stack blown." << llendl;  	} -	mUIOffset.pop_front(); -	mUIScale.pop_front(); +	mUIOffset.pop_back(); +	mUIScale.pop_back();  }  LLVector3 LLRender::getUITranslation() @@ -903,7 +903,7 @@ LLVector3 LLRender::getUITranslation()  	{  		llerrs << "UI offset stack empty." << llendl;  	} -	return mUIOffset.front(); +	return mUIOffset.back();  }  LLVector3 LLRender::getUIScale() @@ -912,7 +912,7 @@ LLVector3 LLRender::getUIScale()  	{  		llerrs << "UI scale stack empty." << llendl;  	} -	return mUIScale.front(); +	return mUIScale.back();  } @@ -922,8 +922,8 @@ void LLRender::loadUIIdentity()  	{  		llerrs << "Need to push UI translation frame before clearing offset." << llendl;  	} -	mUIOffset.front().setVec(0,0,0); -	mUIScale.front().setVec(1,1,1); +	mUIOffset.back().setVec(0,0,0); +	mUIScale.back().setVec(1,1,1);  }  void LLRender::setColorMask(bool writeColor, bool writeAlpha) @@ -1210,18 +1210,79 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)  	}  	else  	{ -		LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.front()).scaledVec(mUIScale.front()); +		LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back());  		mVerticesp[mCount] = vert;  	}  	mCount++; -	if (mCount < 4096) +	mVerticesp[mCount] = mVerticesp[mCount-1]; +	mColorsp[mCount] = mColorsp[mCount-1]; +	mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; +} + +void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count) +{ +	if (mCount + vert_count > 4094)  	{ -		mVerticesp[mCount] = mVerticesp[mCount-1]; -		mColorsp[mCount] = mColorsp[mCount-1]; +		//	llwarns << "GL immediate mode overflow.  Some geometry not drawn." << llendl; +		return; +	} + +	for (S32 i = 0; i < vert_count; i++) +	{ +		mVerticesp[mCount] = verts[i]; + +		mCount++;  		mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; +		mColorsp[mCount] = mColorsp[mCount-1];  	} + +	mVerticesp[mCount] = mVerticesp[mCount-1];  } + +void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count) +{ +	if (mCount + vert_count > 4094) +	{ +		//	llwarns << "GL immediate mode overflow.  Some geometry not drawn." << llendl; +		return; +	} + +	for (S32 i = 0; i < vert_count; i++) +	{ +		mVerticesp[mCount] = verts[i]; +		mTexcoordsp[mCount] = uvs[i]; + +		mCount++; +		mColorsp[mCount] = mColorsp[mCount-1]; +	} + +	mVerticesp[mCount] = mVerticesp[mCount-1]; +	mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; +} + +void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count) +{ +	if (mCount + vert_count > 4094) +	{ +		//	llwarns << "GL immediate mode overflow.  Some geometry not drawn." << llendl; +		return; +	} + +	for (S32 i = 0; i < vert_count; i++) +	{ +		mVerticesp[mCount] = verts[i]; +		mTexcoordsp[mCount] = uvs[i]; +		mColorsp[mCount] = colors[i]; + +		mCount++; +	} + +	mVerticesp[mCount] = mVerticesp[mCount-1]; +	mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; +	mColorsp[mCount] = mColorsp[mCount-1]; +} +  void LLRender::vertex2i(const GLint& x, const GLint& y)  {  	vertex3f((GLfloat) x, (GLfloat) y, 0);	 diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index f6c87aa1db..0fa503182e 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -317,6 +317,10 @@ public:  	void color3fv(const GLfloat* c);  	void color4ubv(const GLubyte* c); +	void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count); +	void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count); +	void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count); +  	void setColorMask(bool writeColor, bool writeAlpha);  	void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);  	void setSceneBlendType(eBlendType type); @@ -373,8 +377,8 @@ private:  	F32				mMaxAnisotropy; -	std::list<LLVector3> mUIOffset; -	std::list<LLVector3> mUIScale; +	std::vector<LLVector3> mUIOffset; +	std::vector<LLVector3> mUIScale;  }; diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp index 43c21e250c..55329f64e4 100644 --- a/indra/llui/lllocalcliprect.cpp +++ b/indra/llui/lllocalcliprect.cpp @@ -33,33 +33,8 @@  #include "lllocalcliprect.h"  #include "llfontgl.h" -#include "llgl.h"  #include "llui.h" -#include <stack> - -//--------------------------------------------------------------------------- -// LLScreenClipRect -// implementation class in screen space -//--------------------------------------------------------------------------- -class LLScreenClipRect -{ -public: -	LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE); -	virtual ~LLScreenClipRect(); - -private: -	static void pushClipRect(const LLRect& rect); -	static void popClipRect(); -	static void updateScissorRegion(); - -private: -	LLGLState		mScissorState; -	BOOL			mEnabled; - -	static std::stack<LLRect> sClipRectStack; -}; -  /*static*/ std::stack<LLRect> LLScreenClipRect::sClipRectStack; @@ -131,16 +106,11 @@ void LLScreenClipRect::updateScissorRegion()  // LLLocalClipRect  //---------------------------------------------------------------------------  LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */) -{ -	LLRect screen(rect.mLeft + LLFontGL::sCurOrigin.mX,  -		rect.mTop + LLFontGL::sCurOrigin.mY,  -		rect.mRight + LLFontGL::sCurOrigin.mX,  -		rect.mBottom + LLFontGL::sCurOrigin.mY); -	mScreenClipRect = new LLScreenClipRect(screen, enabled); -} +:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,  +					rect.mTop + LLFontGL::sCurOrigin.mY,  +					rect.mRight + LLFontGL::sCurOrigin.mX,  +					rect.mBottom + LLFontGL::sCurOrigin.mY), enabled) +{}  LLLocalClipRect::~LLLocalClipRect() -{ -	delete mScreenClipRect; -	mScreenClipRect = NULL; -} +{} diff --git a/indra/llui/lllocalcliprect.h b/indra/llui/lllocalcliprect.h index cd0c55ca72..36413f1496 100644 --- a/indra/llui/lllocalcliprect.h +++ b/indra/llui/lllocalcliprect.h @@ -31,7 +31,9 @@  #ifndef LLLOCALCLIPRECT_H  #define LLLOCALCLIPRECT_H +#include "llgl.h"  #include "llrect.h"		// can't forward declare, it's templated +#include <stack>  // Clip rendering to a specific rectangle using GL scissor  // Just create one of these on the stack: @@ -39,15 +41,29 @@  //     LLLocalClipRect(rect);  //     draw();  // } -class LLLocalClipRect +class LLScreenClipRect  {  public: -	LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); -	~LLLocalClipRect(); +	LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE); +	virtual ~LLScreenClipRect(); + +private: +	static void pushClipRect(const LLRect& rect); +	static void popClipRect(); +	static void updateScissorRegion();  private: -	// implementation class -	class LLScreenClipRect* mScreenClipRect; +	LLGLState		mScissorState; +	BOOL			mEnabled; + +	static std::stack<LLRect> sClipRectStack; +}; + +class LLLocalClipRect : public LLScreenClipRect +{ +public: +	LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); +	~LLLocalClipRect();  };  #endif diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 34d58db7f8..a580345b6c 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1012,22 +1012,25 @@ void LLTextBase::draw()  	if (mBGVisible)  	{  		// clip background rect against extents, if we support scrolling -		LLLocalClipRect clip(doc_rect, mScroller != NULL); - +		LLRect bg_rect = mVisibleTextRect; +		if (mScroller) +		{ +			bg_rect.intersectWith(doc_rect); +		}  		LLColor4 bg_color = mReadOnly   							? mReadOnlyBgColor.get()  							: hasFocus()   								? mFocusBgColor.get()   								: mWriteableBgColor.get(); -		gl_rect_2d(mVisibleTextRect, bg_color, TRUE); +		gl_rect_2d(doc_rect, bg_color, TRUE);  	}  	// draw document view  	LLUICtrl::draw();  	{ -		// only clip if we support scrolling (mScroller != NULL) -		LLLocalClipRect clip(doc_rect, mScroller != NULL); +		// only clip if we support scrolling or have word wrap turned off +		LLLocalClipRect clip(doc_rect, !getWordWrap() || mScroller != NULL);  		drawSelectionBackground();  		drawText();  		drawCursor(); @@ -1495,6 +1498,7 @@ LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index)  	// when there are no segments, we return the end iterator, which must be checked by caller  	if (mSegments.size() <= 1) { return mSegments.begin(); } +	//FIXME: avoid operator new somehow (without running into refcount problems)  	segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index));  	return it;  } @@ -1790,7 +1794,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig  		}  		else  		{ -			segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this )); +		segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this ));  		}  		insertStringNoUndo(getLength(), wide_text, &segments); @@ -2289,6 +2293,7 @@ void LLTextBase::updateRects()  	// allow horizontal scrolling?  	// if so, use entire width of text contents  	// otherwise, stop at width of mVisibleTextRect +	//FIXME: consider use of getWordWrap() instead  	doc_rect.mRight = mScroller   		? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight)  		: mVisibleTextRect.getWidth();  | 
