diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 91e0eb8e5199c31e6649431378a2a451e9e29e69..636d140827147db9aa43ff9da7fb2c5e672bfc52 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -230,7 +230,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
 	x_max = mFTFace->bbox.xMax * pixels_per_unit;
 	x_min = mFTFace->bbox.xMin * pixels_per_unit;
 	mAscender = mFTFace->ascender * pixels_per_unit;
-	mDescender = -mFTFace->descender * pixels_per_unit;
+	mDescender = -(mFTFace->descender * pixels_per_unit);
 	mLineHeight = mFTFace->height * pixels_per_unit;
 
 	S32 max_char_width = ll_round(0.5f + (x_max - x_min));
@@ -332,7 +332,7 @@ F32 LLFontFreetype::getDescenderHeight() const
 F32 LLFontFreetype::getXAdvance(llwchar wch) const
 {
 	if (mFTFace == NULL)
-		return 0.0;
+		return 0.f;
 
 	// Return existing info only if it is current
 	LLFontGlyphInfo* gi = getGlyphInfo(wch);
@@ -356,40 +356,22 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const
 F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const
 {
 	if (mFTFace == NULL)
-		return 0.0;
+		return 0.f;
 
 	return glyph->mXAdvance;
 }
 
 F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
 {
-	if (mFTFace == NULL)
-		return 0.0;
-
-	//llassert(!mIsFallback);
 	LLFontGlyphInfo* left_glyph_info = getGlyphInfo(char_left);;
-	U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
-	// Kern this puppy.
 	LLFontGlyphInfo* right_glyph_info = getGlyphInfo(char_right);
-	U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
-
-	F32 kerning = 0.0f;
-	if (getKerningCache(left_glyph,  right_glyph, kerning))
-		return kerning;
-
-	FT_Vector  delta;
-
-	llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, FT_KERNING_DEFAULT, &delta));
-
-	kerning = delta.x*(1.f/64.f);
-	setKerningCache(left_glyph, right_glyph, kerning);
-	return kerning;
+	return getXKerning(left_glyph_info, right_glyph_info);
 }
 
 F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const
 {
 	if (mFTFace == nullptr)
-		return 0.0;
+		return 0.f;
 
 	U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
 	U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
@@ -398,11 +380,20 @@ F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LL
 	if (getKerningCache(left_glyph,  right_glyph, kerning))
 		return kerning;
 
-	FT_Vector  delta;
+    FT_Vector delta;
+    delta.x = delta.y = 0;
+	if(FT_HAS_KERNING(mFTFace))
+	    FT_Get_Kerning(mFTFace, left_glyph, right_glyph, FT_KERNING_UNFITTED, &delta);
 
-	llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, FT_KERNING_DEFAULT, &delta));
+	if (!FT_IS_SCALABLE(mFTFace))
+		kerning = static_cast<float>(delta.x);
+	else
+	{
+	    S32 left_delta = left_glyph_info ? left_glyph_info->mRightSideBearingDelta : 0;
+	    S32 right_delta = right_glyph_info ? right_glyph_info->mLeftSideBearingDelta : 0;
+		kerning = llfloor((right_delta - left_delta + static_cast<float>(delta.x) + 32) / 64.f);
+	}
 
-	kerning = delta.x*(1.f/64.f);
 	setKerningCache(left_glyph, right_glyph, kerning);
 	return kerning;
 }
@@ -470,8 +461,10 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l
 	gi->mXBearing = fontp->mFTFace->glyph->bitmap_left;
 	gi->mYBearing = fontp->mFTFace->glyph->bitmap_top;
 	// Convert these from 26.6 units to float pixels.
-	gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
-	gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
+	gi->mXAdvance = fontp->mFTFace->glyph->advance.x * (1.f/64.f);
+	gi->mYAdvance = fontp->mFTFace->glyph->advance.y * (1.f/64.f);
+	gi->mRightSideBearingDelta = fontp->mFTFace->glyph->rsb_delta;
+	gi->mLeftSideBearingDelta = fontp->mFTFace->glyph->lsb_delta;
 
 	insertGlyphInfo(wch, gi);
 
@@ -583,10 +576,10 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const
 	if (mFTFace == NULL)
 		return;
 
-	if (FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_RENDER | FT_LOAD_TARGET_LIGHT) != 0)
+	if (FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT) != 0)
 	{
 		// If glyph fails to load and/or render, render a fallback character
-		llassert_always(!FT_Load_Char(mFTFace, static_cast<FT_ULong>('?'), FT_LOAD_RENDER | FT_LOAD_TARGET_LIGHT));
+		llassert_always(!FT_Load_Char(mFTFace, static_cast<FT_ULong>('?'), FT_LOAD_DEFAULT || FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT));
 	}
 
 	mRenderGlyphCount++;
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index cd8705f1934ea27f05b73cf46f6d66c106551ea6..9507ef0c90f1030d196dcbc14246bdf84a8a7694 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -91,6 +91,8 @@ struct LLFontGlyphInfo
 	S32 mXBearing;	// Distance from baseline to left in pixels
 	S32 mYBearing;	// Distance from baseline to top in pixels
 	S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph
+	S32 mRightSideBearingDelta;
+	S32 mLeftSideBearingDelta;
 };
 
 extern LLFontManager *gFontManagerp;
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 30ec1c771f495d62d0a73cc9187a1deef234f414..f1b80797c92bd7ce37efe401814e2f6259e3cf6f 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -355,13 +355,6 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
 			cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
 		}
 
-		// Round after kerning.
-		// Must do this to cur_x, not just to cur_render_x, otherwise you
-		// will squish sub-pixel kerned characters too close together.
-		// For example, "CCCCC" looks bad.
-		cur_x = (F32)ll_round(cur_x);
-		//cur_y = (F32)ll_round(cur_y);
-
 		cur_render_x = cur_x;
 		cur_render_y = cur_y;
 	}
@@ -534,8 +527,6 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
 			next_glyph = mFontFreetype->getGlyphInfo(next_char);
 			cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
 		}
-		// Round after kerning.
-		cur_x = (F32)ll_round(cur_x);
 	}
 
 	// add in extra pixels for last character's width past its xadvance
@@ -641,9 +632,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 			next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1]);
 			cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
 		}
-
-		// Round after kerning.
-		cur_x = (F32)ll_round(cur_x);
 	}
 
 	if( clip )
@@ -711,9 +699,6 @@ S32	LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
 			// kerning
 			total_width += mFontFreetype->getXKerning(wchars[i-1], wch);
 		}
-
-		// Round after kerning.
-		total_width = (F32)ll_round(total_width);
 	}
 
 	if (drawable_chars == 0)
@@ -793,10 +778,6 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
 			next_glyph = mFontFreetype->getGlyphInfo(wchars[pos + 1]);
 			cur_x += mFontFreetype->getXKerning(glyph, next_glyph);
 		}
-
-
-		// Round after kerning.
-		cur_x = (F32)ll_round(cur_x);
 	}
 
 	return llmin(max_chars, pos - begin_offset);