123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /**
- * @file llfontbitmapcache.cpp
- * @brief Storage for previously rendered glyphs.
- *
- * $LicenseInfo:firstyear=2008&license=viewergpl$
- *
- * Copyright (c) 2008-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include "llfontbitmapcache.h"
- #include "llgl.h"
- LLFontBitmapCache::LLFontBitmapCache()
- : mMaxCharWidth(0),
- mMaxCharHeight(0),
- mBitmapWidth(0),
- mBitmapHeight(0)
- {
- // Note: we cheat for speed, avoiding a for() loop. This works as long as
- // EFontGlyphType::Count == 2. HB
- mCurrentOffsetX[0] = mCurrentOffsetX[1] = 1;
- mCurrentOffsetY[0] = mCurrentOffsetY[1] = 1;
- }
- void LLFontBitmapCache::reset()
- {
- mBitmapWidth = mBitmapHeight = 0;
- // Note: we cheat for speed, avoiding a for() loop. This works as long as
- // EFontGlyphType::Count == 2. HB
- mImageRawVec[0].clear();
- mImageRawVec[1].clear();
- mImageGLVec[0].clear();
- mImageGLVec[1].clear();
- mCurrentOffsetX[0] = mCurrentOffsetX[1] = 1;
- mCurrentOffsetY[0] = mCurrentOffsetY[1] = 1;
- }
- void LLFontBitmapCache::init(S32 max_char_width, S32 max_char_height)
- {
- reset();
- mMaxCharWidth = max_char_width;
- mMaxCharHeight = max_char_height;
- S32 image_width = mMaxCharWidth * 20;
- S32 pow_iw = 2;
- while (pow_iw < image_width)
- {
- pow_iw *= 2;
- }
- image_width = llmin(pow_iw, 512); // Never bigger than 512x512 !
- mBitmapWidth = mBitmapHeight = image_width;
- }
- LLImageRaw* LLFontBitmapCache::getImageRaw(U32 b_type, U32 b_num) const
- {
- if (b_type >= EFontGlyphType::Count ||
- (size_t)b_num >= mImageRawVec[b_type].size())
- {
- return NULL;
- }
- return mImageRawVec[b_type][b_num].get();
- }
- LLImageGL* LLFontBitmapCache::getImageGL(U32 b_type, U32 b_num) const
- {
- if (b_type >= EFontGlyphType::Count ||
- (size_t)b_num >= mImageGLVec[b_type].size())
- {
- return NULL;
- }
- return mImageGLVec[b_type][b_num].get();
- }
- void LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y,
- U32 b_type, U32& bitmap_num)
- {
- if (b_type >= EFontGlyphType::Count)
- {
- return;
- }
- bool no_image = mImageRawVec[b_type].empty();
- if (no_image || mCurrentOffsetX[b_type] + width + 1 > mBitmapWidth)
- {
- if (no_image ||
- mCurrentOffsetY[b_type] + 2 * mMaxCharHeight + 2 > mBitmapHeight)
- {
- // We Are out of space in the current image, or no image has been
- // allocated yet. Make a new one.
- S32 image_width = mMaxCharWidth * 20;
- S32 pow_iw = 2;
- while (pow_iw < image_width)
- {
- pow_iw *= 2;
- }
- image_width = llmin(pow_iw, 512); // Never bigger than 512x512 !
- S32 image_height = image_width;
- mBitmapWidth = image_width;
- mBitmapHeight = image_height;
- U32 num_components = getNumComponents(b_type);
- mImageRawVec[b_type].emplace_back(new LLImageRaw(mBitmapWidth,
- mBitmapHeight,
- num_components));
- bitmap_num = mImageRawVec[b_type].size() - 1;
- LLImageRaw* imagep = getImageRaw(b_type, bitmap_num);
- if (num_components == 2)
- {
- imagep->clear(255, 0);
- }
- // Make corresponding GL image.
- mImageGLVec[b_type].emplace_back(new LLImageGL(imagep, false));
- LLImageGL* glimgp = getImageGL(b_type, bitmap_num);
- // Start at beginning of the new image.
- mCurrentOffsetX[b_type] = 1;
- mCurrentOffsetY[b_type] = 1;
- // Attach corresponding GL texture.
- gGL.getTexUnit(0)->bind(glimgp);
- // Was: setMipFilterNearest(true, true);
- glimgp->setFilteringOption(LLTexUnit::TFO_POINT);
- }
- else
- {
- // Move to next row in current image.
- mCurrentOffsetX[b_type] = 1;
- mCurrentOffsetY[b_type] += mMaxCharHeight + 1;
- }
- }
- pos_x = mCurrentOffsetX[b_type];
- pos_y = mCurrentOffsetY[b_type];
- bitmap_num = getNumBitmaps(b_type) - 1;
- mCurrentOffsetX[b_type] += width + 1;
- }
- void LLFontBitmapCache::destroyGL()
- {
- for (U32 j = 0; j < EFontGlyphType::Count; ++j)
- {
- for (size_t i = 0, count = mImageGLVec[j].size(); i < count; ++i)
- {
- mImageGLVec[j][i]->destroyGLTexture();
- }
- }
- }
|