aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender/llfontgl.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:54 -0500
committerJacek Antonelli2008-08-15 23:44:54 -0500
commitb2afb8800bb033a04bb3ecdf0363068d56648ef1 (patch)
tree3568129b5bbddb47cd39d622b4137a8fbff4abaf /linden/indra/llrender/llfontgl.cpp
parentSecond Life viewer sources 1.14.0.1 (diff)
downloadmeta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.zip
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.gz
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.bz2
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.xz
Second Life viewer sources 1.15.0.2
Diffstat (limited to 'linden/indra/llrender/llfontgl.cpp')
-rw-r--r--linden/indra/llrender/llfontgl.cpp194
1 files changed, 112 insertions, 82 deletions
diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp
index f72a7de..7ee89c7 100644
--- a/linden/indra/llrender/llfontgl.cpp
+++ b/linden/indra/llrender/llfontgl.cpp
@@ -4,6 +4,7 @@
4 * 4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 * 6 *
7 * Second Life Viewer Source Code
7 * The source code in this file ("Source Code") is provided by Linden Lab 8 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0 9 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement 10 * ("GPL"), unless you have obtained a separate licensing agreement
@@ -69,6 +70,7 @@ const F32 PIXEL_BORDER_THRESHOLD = 0.0001f;
69const F32 PIXEL_CORRECTION_DISTANCE = 0.01f; 70const F32 PIXEL_CORRECTION_DISTANCE = 0.01f;
70 71
71const F32 PAD_AMT = 0.5f; 72const F32 PAD_AMT = 0.5f;
73const F32 DROP_SHADOW_STRENGTH = 0.3f;
72 74
73F32 llfont_round_x(F32 x) 75F32 llfont_round_x(F32 x)
74{ 76{
@@ -133,7 +135,8 @@ void LLFontGL::init()
133 mImageGLp = new LLImageGL(FALSE); 135 mImageGLp = new LLImageGL(FALSE);
134 //RN: use nearest mipmap filtering to obviate the need to do pixel-accurate positioning 136 //RN: use nearest mipmap filtering to obviate the need to do pixel-accurate positioning
135 mImageGLp->bind(); 137 mImageGLp->bind();
136 mImageGLp->setMipFilterNearest(TRUE, TRUE); 138 // we allow bilinear filtering to get sub-pixel positioning for drop shadows
139 //mImageGLp->setMipFilterNearest(TRUE, TRUE);
137 } 140 }
138 if (mRawImageGLp.isNull()) 141 if (mRawImageGLp.isNull())
139 { 142 {
@@ -549,28 +552,8 @@ S32 LLFontGL::render(const LLWString &wstr,
549 return 0; 552 return 0;
550 } 553 }
551 554
552 if (style & DROP_SHADOW)
553 {
554 LLColor4 shadow_color = sShadowColor;
555 shadow_color[3] = color[3];
556 render(wstr, begin_offset,
557 x + 1.f / sScaleX,
558 y - 1.f / sScaleY,
559 shadow_color,
560 halign,
561 valign,
562 style & (~DROP_SHADOW),
563 max_chars,
564 max_pixels,
565 right_x,
566 use_embedded,
567 use_ellipses);
568 }
569
570 S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX); 555 S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX);
571 556
572 BOOL render_bold = FALSE;
573
574 // HACK for better bolding 557 // HACK for better bolding
575 if (style & BOLD) 558 if (style & BOLD)
576 { 559 {
@@ -585,9 +568,17 @@ S32 LLFontGL::render(const LLWString &wstr,
585 max_chars, max_pixels, 568 max_chars, max_pixels,
586 right_x, use_embedded); 569 right_x, use_embedded);
587 } 570 }
588 else 571 }
572
573 F32 drop_shadow_strength = 0.f;
574 if (style & DROP_SHADOW)
575 {
576 F32 luminance;
577 color.calcHSL(NULL, NULL, &luminance);
578 drop_shadow_strength = clamp_rescale(luminance, 0.35f, 0.6f, 0.f, DROP_SHADOW_STRENGTH);
579 if (luminance < 0.35f)
589 { 580 {
590 render_bold = TRUE; 581 style = style & ~DROP_SHADOW;
591 } 582 }
592 } 583 }
593 584
@@ -631,9 +622,6 @@ S32 LLFontGL::render(const LLWString &wstr,
631 } 622 }
632 623
633 F32 cur_x, cur_y, cur_render_x, cur_render_y; 624 F32 cur_x, cur_y, cur_render_x, cur_render_y;
634 F32 slant_offset;
635
636 slant_offset = ((style & ITALIC) ? ( -mAscender * 0.25f) : 0.f);
637 625
638 // Bind the font texture 626 // Bind the font texture
639 627
@@ -696,7 +684,7 @@ S32 LLFontGL::render(const LLWString &wstr,
696 if (use_ellipses && halign == LEFT) 684 if (use_ellipses && halign == LEFT)
697 { 685 {
698 // check for too long of a string 686 // check for too long of a string
699 if (getWidthF32(wstr.c_str(), 0, max_chars) > scaled_max_pixels) 687 if (getWidthF32(wstr.c_str(), 0, max_chars) * sScaleX > scaled_max_pixels)
700 { 688 {
701 // use four dots for ellipsis width to generate padding 689 // use four dots for ellipsis width to generate padding
702 const LLWString dots(utf8str_to_wstring(LLString("...."))); 690 const LLWString dots(utf8str_to_wstring(LLString("....")));
@@ -706,7 +694,6 @@ S32 LLFontGL::render(const LLWString &wstr,
706 } 694 }
707 695
708 696
709 glBegin(GL_QUADS);
710 for (i = begin_offset; i < begin_offset + length; i++) 697 for (i = begin_offset; i < begin_offset + length; i++)
711 { 698 {
712 llwchar wch = wstr[i]; 699 llwchar wch = wstr[i];
@@ -735,36 +722,13 @@ S32 LLFontGL::render(const LLWString &wstr,
735 break; 722 break;
736 } 723 }
737 724
738 glEnd();
739
740 glColor3f(1.f, 1.f, 1.f);
741
742 ext_image->bind(); 725 ext_image->bind();
743 const F32 ext_x = cur_render_x + (EXT_X_BEARING * sScaleX); 726 const F32 ext_x = cur_render_x + (EXT_X_BEARING * sScaleX);
744 const F32 ext_y = cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight); 727 const F32 ext_y = cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight);
745 728
746 glBegin(GL_QUADS); 729 LLRectf uv_rect(0.f, 1.f, 1.f, 0.f);
747 { 730 LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y);
748 S32 num_passes = render_bold ? 2 : 1; 731 drawGlyph(screen_rect, uv_rect, LLColor4::white, style, drop_shadow_strength);
749 for (S32 pass = 0; pass < num_passes; pass++)
750 {
751 glTexCoord2f(1.f, 1.f);
752 glVertex2f(llfont_round_x(ext_x + ext_width + (F32)(pass * BOLD_OFFSET)),
753 llfont_round_y(ext_y + ext_height));
754
755 glTexCoord2f(0.f, 1.f);
756 glVertex2f(llfont_round_x(ext_x + (F32)(pass * BOLD_OFFSET)),
757 llfont_round_y(ext_y + ext_height));
758
759 glTexCoord2f(0.f, 0.f);
760 glVertex2f(llfont_round_x(ext_x + (F32)(pass * BOLD_OFFSET)), llfont_round_y(ext_y));
761
762 glTexCoord2f(1.f, 0.f);
763 glVertex2f(llfont_round_x(ext_x + ext_width + (F32)(pass * BOLD_OFFSET)),
764 llfont_round_y(ext_y));
765 }
766 }
767 glEnd();
768 732
769 if (!label.empty()) 733 if (!label.empty())
770 { 734 {
@@ -793,15 +757,12 @@ S32 LLFontGL::render(const LLWString &wstr,
793 757
794 // Bind the font texture 758 // Bind the font texture
795 mImageGLp->bind(); 759 mImageGLp->bind();
796 glBegin(GL_QUADS);
797 } 760 }
798 else 761 else
799 { 762 {
800 if (!hasGlyph(wch)) 763 if (!hasGlyph(wch))
801 { 764 {
802 glEnd();
803 (const_cast<LLFontGL*>(this))->addChar(wch); 765 (const_cast<LLFontGL*>(this))->addChar(wch);
804 glBegin(GL_QUADS);
805 } 766 }
806 767
807 const LLFontGlyphInfo* fgi= getGlyphInfo(wch); 768 const LLFontGlyphInfo* fgi= getGlyphInfo(wch);
@@ -817,40 +778,28 @@ S32 LLFontGL::render(const LLWString &wstr,
817 778
818 // Draw the text at the appropriate location 779 // Draw the text at the appropriate location
819 //Specify vertices and texture coordinates 780 //Specify vertices and texture coordinates
820 S32 num_passes = render_bold ? 2 : 1; 781 LLRectf uv_rect((fgi->mXBitmapOffset - PAD_AMT) * inv_width,
821 for (S32 pass = 0; pass < num_passes; pass++) 782 (fgi->mYBitmapOffset + fgi->mHeight + PAD_AMT) * inv_height,
822 { 783 (fgi->mXBitmapOffset + fgi->mWidth + PAD_AMT) * inv_width,
823 glTexCoord2f((fgi->mXBitmapOffset - PAD_AMT) * inv_width, 784 (fgi->mYBitmapOffset - PAD_AMT) * inv_height);
824 (fgi->mYBitmapOffset + fgi->mHeight + PAD_AMT) * inv_height); 785 LLRectf screen_rect(cur_render_x + (F32)fgi->mXBearing - PAD_AMT,
825 glVertex2f(llfont_round_x(cur_render_x + (F32)fgi->mXBearing + (F32)(pass * BOLD_OFFSET) - PAD_AMT), 786 cur_render_y + (F32)fgi->mYBearing + PAD_AMT,
826 llfont_round_y(cur_render_y + (F32)fgi->mYBearing + PAD_AMT)); 787 cur_render_x + (F32)fgi->mXBearing + (F32)fgi->mWidth + PAD_AMT,
827 glTexCoord2f((fgi->mXBitmapOffset - PAD_AMT) * inv_width, 788 cur_render_y + (F32)fgi->mYBearing - (F32)fgi->mHeight - PAD_AMT);
828 (fgi->mYBitmapOffset - PAD_AMT) * inv_height);
829 glVertex2f(llfont_round_x(cur_render_x + (F32)fgi->mXBearing + slant_offset + (F32)(pass * BOLD_OFFSET) - PAD_AMT),
830 llfont_round_y(cur_render_y + (F32)fgi->mYBearing - (F32)fgi->mHeight - PAD_AMT));
831 glTexCoord2f((fgi->mXBitmapOffset + fgi->mWidth + PAD_AMT) * inv_width,
832 (fgi->mYBitmapOffset - PAD_AMT) * inv_height);
833 glVertex2f(llfont_round_x(cur_render_x + (F32)fgi->mXBearing + slant_offset + (F32)fgi->mWidth + (F32)(pass * BOLD_OFFSET) + PAD_AMT),
834 llfont_round_y(cur_render_y + (F32)fgi->mYBearing - (F32)fgi->mHeight - PAD_AMT));
835 glTexCoord2f((fgi->mXBitmapOffset + fgi->mWidth + PAD_AMT) * inv_width,
836 (fgi->mYBitmapOffset + fgi->mHeight + PAD_AMT) * inv_height);
837 glVertex2f(llfont_round_x(cur_render_x + (F32)fgi->mXBearing + (F32)fgi->mWidth + (F32)(pass * BOLD_OFFSET) + PAD_AMT),
838 llfont_round_y(cur_render_y + (F32)fgi->mYBearing + PAD_AMT));
839 }
840 789
841 chars_drawn++; 790 drawGlyph(screen_rect, uv_rect, color, style, drop_shadow_strength);
842 791
792 chars_drawn++;
843 cur_x += fgi->mXAdvance; 793 cur_x += fgi->mXAdvance;
844 cur_y += fgi->mYAdvance; 794 cur_y += fgi->mYAdvance;
795
845 llwchar next_char = wstr[i+1]; 796 llwchar next_char = wstr[i+1];
846 if (next_char && (next_char < LAST_CHARACTER)) 797 if (next_char && (next_char < LAST_CHARACTER))
847 { 798 {
848 // Kern this puppy. 799 // Kern this puppy.
849 if (!hasGlyph(next_char)) 800 if (!hasGlyph(next_char))
850 { 801 {
851 glEnd();
852 (const_cast<LLFontGL*>(this))->addChar(next_char); 802 (const_cast<LLFontGL*>(this))->addChar(next_char);
853 glBegin(GL_QUADS);
854 } 803 }
855 cur_x += getXKerning(wch, next_char); 804 cur_x += getXKerning(wch, next_char);
856 } 805 }
@@ -867,8 +816,6 @@ S32 LLFontGL::render(const LLWString &wstr,
867 } 816 }
868 } 817 }
869 818
870 glEnd();
871
872 if (right_x) 819 if (right_x)
873 { 820 {
874 *right_x = cur_x / sScaleX; 821 *right_x = cur_x / sScaleX;
@@ -1347,6 +1294,89 @@ void LLFontGL::removeEmbeddedChar( llwchar wc )
1347 } 1294 }
1348} 1295}
1349 1296
1297
1298void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const
1299{
1300 glTexCoord2f(uv_rect.mRight, uv_rect.mTop);
1301 glVertex2f(llfont_round_x(screen_rect.mRight),
1302 llfont_round_y(screen_rect.mTop));
1303
1304 glTexCoord2f(uv_rect.mLeft, uv_rect.mTop);
1305 glVertex2f(llfont_round_x(screen_rect.mLeft),
1306 llfont_round_y(screen_rect.mTop));
1307
1308 glTexCoord2f(uv_rect.mLeft, uv_rect.mBottom);
1309 glVertex2f(llfont_round_x(screen_rect.mLeft + slant_amt),
1310 llfont_round_y(screen_rect.mBottom));
1311
1312 glTexCoord2f(uv_rect.mRight, uv_rect.mBottom);
1313 glVertex2f(llfont_round_x(screen_rect.mRight + slant_amt),
1314 llfont_round_y(screen_rect.mBottom));
1315}
1316
1317void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, F32 drop_shadow_strength) const
1318{
1319 F32 slant_offset;
1320 slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f);
1321
1322 glBegin(GL_QUADS);
1323 {
1324 //FIXME: bold and drop shadow are mutually exclusive only for convenience
1325 //Allow both when we need them.
1326 if (style & BOLD)
1327 {
1328 glColor4fv(color.mV);
1329 for (S32 pass = 0; pass < 2; pass++)
1330 {
1331 LLRectf screen_rect_offset = screen_rect;
1332
1333 screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f);
1334 renderQuad(screen_rect_offset, uv_rect, slant_offset);
1335 }
1336 }
1337 else if (style & DROP_SHADOW)
1338 {
1339 LLColor4 shadow_color = LLFontGL::sShadowColor;
1340 shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength;
1341 glColor4fv(shadow_color.mV);
1342 for (S32 pass = 0; pass < 5; pass++)
1343 {
1344 LLRectf screen_rect_offset = screen_rect;
1345
1346 switch(pass)
1347 {
1348 case 0:
1349 screen_rect_offset.translate(-1.f, -1.f);
1350 break;
1351 case 1:
1352 screen_rect_offset.translate(1.f, -1.f);
1353 break;
1354 case 2:
1355 screen_rect_offset.translate(1.f, 1.f);
1356 break;
1357 case 3:
1358 screen_rect_offset.translate(-1.f, 1.f);
1359 break;
1360 case 4:
1361 screen_rect_offset.translate(0, -2.f);
1362 break;
1363 }
1364
1365 renderQuad(screen_rect_offset, uv_rect, slant_offset);
1366 }
1367 glColor4fv(color.mV);
1368 renderQuad(screen_rect, uv_rect, slant_offset);
1369 }
1370 else // normal rendering
1371 {
1372 glColor4fv(color.mV);
1373 renderQuad(screen_rect, uv_rect, slant_offset);
1374 }
1375
1376 }
1377 glEnd();
1378}
1379
1350// static 1380// static
1351LLString LLFontGL::nameFromFont(const LLFontGL* fontp) 1381LLString LLFontGL::nameFromFont(const LLFontGL* fontp)
1352{ 1382{