You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
7.7 KiB
C++
201 lines
7.7 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
// Purpose:
|
|
// - Manage and cache glyphs, retrieving them from the renderer as needed
|
|
|
|
#ifndef CRYINCLUDE_CRYFONT_GLYPHCACHE_H
|
|
#define CRYINCLUDE_CRYFONT_GLYPHCACHE_H
|
|
#pragma once
|
|
|
|
#if !defined(USE_NULLFONT_ALWAYS)
|
|
|
|
#include <vector>
|
|
#include "GlyphBitmap.h"
|
|
#include "FontRenderer.h"
|
|
#include "CryFont.h"
|
|
#include <StlUtils.h>
|
|
|
|
//! Glyph cache slots store the bitmap buffer and glyph metadata from FreeType.
|
|
//!
|
|
//! This bitmap buffer is eventually copied to a CFontTexture texture buffer.
|
|
//! A glyph cache slot bitmap buffer only holds a single glyph, whereas the
|
|
//! CFontTexture stores multiple glyphs in a grid (row/col) format.
|
|
typedef struct CCacheSlot
|
|
{
|
|
Vec2i glyphSize = CCryFont::defaultGlyphSize; //!< The render resolution of the glyph in the glyph bitmap
|
|
unsigned int dwUsage;
|
|
int iCacheSlot;
|
|
int iHoriAdvance; //!< Advance width. See FT_Glyph_Metrics::horiAdvance.
|
|
uint32 cCurrentChar;
|
|
|
|
uint8 iCharWidth; //!< Glyph width (in pixel)
|
|
uint8 iCharHeight; //!< Glyph height (in pixel)
|
|
AZ::s32 iCharOffsetX; //!< Glyph's left-side bearing (in pixels). See FT_GlyphSlotRec::bitmap_left.
|
|
AZ::s32 iCharOffsetY; //!< Glyph's top bearing (in pixels). See FT_GlyphSlotRec::bitmap_top.
|
|
|
|
CGlyphBitmap pGlyphBitmap; //!< Contains a buffer storing a copy of the glyph from FreeType
|
|
|
|
void Reset()
|
|
{
|
|
dwUsage = 0;
|
|
cCurrentChar = ~0;
|
|
|
|
iCharWidth = 0;
|
|
iCharHeight = 0;
|
|
iCharOffsetX = 0;
|
|
iCharOffsetY = 0;
|
|
|
|
pGlyphBitmap.Clear();
|
|
}
|
|
|
|
void GetMemoryUsage(ICrySizer* pSizer) const
|
|
{
|
|
pSizer->AddObject(this, sizeof(*this));
|
|
pSizer->AddObject(pGlyphBitmap);
|
|
}
|
|
} CCacheSlot;
|
|
|
|
namespace CryFont
|
|
{
|
|
namespace GlyphCache
|
|
{
|
|
//! Height and width pair for glyph size mapping
|
|
typedef Vec2i CCacheTableGlyphSizeType;
|
|
|
|
//! Pair for mapping a height and width size to a UTF32 character/glyph
|
|
typedef AZStd::pair<CCacheTableGlyphSizeType, uint32> CCacheTableKey;
|
|
|
|
//! Hasher for glyph cache table keys (glyphsize-char code pair)
|
|
//!
|
|
//! Instead of creating our own custom hash, the types are broken down to their
|
|
//! native types (ints) and passed to existing hashes that handle those types.
|
|
struct HashGlyphCacheTableKey
|
|
{
|
|
typedef CCacheTableKey ArgumentType;
|
|
typedef AZStd::size_t ResultType;
|
|
typedef AZStd::pair<int32, int32> Int32Pair;
|
|
typedef AZStd::pair<Int32Pair, uint32> Int32PairU32Pair;
|
|
ResultType operator()(const ArgumentType& value) const
|
|
{
|
|
AZStd::hash<Int32PairU32Pair> pairHash;
|
|
return pairHash(Int32PairU32Pair(Int32Pair(value.first.x, value.first.y), value.second));
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
//! Maps size-speicifc UTF32 glyphs to their corresponding cache slots
|
|
typedef AZStd::unordered_map<CryFont::GlyphCache::CCacheTableKey, CCacheSlot*, CryFont::GlyphCache::HashGlyphCacheTableKey> CCacheTable;
|
|
|
|
typedef std::vector<CCacheSlot*> CCacheSlotList;
|
|
typedef std::vector<CCacheSlot*>::iterator CCacheSlotListItor;
|
|
|
|
|
|
#ifdef WIN64
|
|
#undef GetCharWidth
|
|
#undef GetCharHeight
|
|
#endif
|
|
|
|
//! The glyph cache maps UTF32 codepoints to their corresponding FreeType data.
|
|
//!
|
|
//! This cache is used to associate font glyph info (read from FreeType) with
|
|
//! UTF32 codepoints. Ultimately the glyph info will be read into a font texture
|
|
//! (CFontTexture) to avoid future FreeType lookups.
|
|
//!
|
|
//! If a CFontTexture is missing a glyph that is currently stored in the glyph
|
|
//! cache, the cached data can be returned instead of having to be rendered from
|
|
//! FreeType again.
|
|
//!
|
|
//! \sa CFontTexture
|
|
class CGlyphCache
|
|
{
|
|
public:
|
|
CGlyphCache();
|
|
~CGlyphCache();
|
|
|
|
int Create(int iCacheSize, int iGlyphBitmapWidth, int iGlyphBitmapHeight, int iSmoothMethod, int iSmoothAmount, float sizeRatio);
|
|
int Release();
|
|
|
|
int LoadFontFromFile(const string& szFileName);
|
|
int LoadFontFromMemory(unsigned char* pFileBuffer, int iDataSize);
|
|
int ReleaseFont();
|
|
|
|
int SetEncoding(FT_Encoding pEncoding) { return m_pFontRenderer.SetEncoding(pEncoding); };
|
|
FT_Encoding GetEncoding() { return m_pFontRenderer.GetEncoding(); };
|
|
|
|
int GetGlyphBitmapSize(int* pWidth, int* pHeight);
|
|
void SetGlyphBitmapSize(int width, int height, float sizeRatio);
|
|
|
|
int PreCacheGlyph(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams());
|
|
int UnCacheGlyph(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize);
|
|
int GlyphCached(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize);
|
|
|
|
CCacheSlot* GetLRUSlot();
|
|
CCacheSlot* GetMRUSlot();
|
|
|
|
//! Obtains glyph information for the given UTF32 codepoint.
|
|
//! This information is obtained from a CCacheSlot that corresponds to
|
|
//! the given codepoint. If the codepoint doesn't exist within the cache
|
|
//! table (m_pCacheTable), then the information is obtain from FreeType
|
|
//! directly via CFontRenderer.
|
|
//!
|
|
//! Ultimately the glyph bitmap is copied into a font texture
|
|
//! (CFontTexture). Once the glyph is copied into the font texture then
|
|
//! the font texture is referenced directly rather than relying on the
|
|
//! glyph cache or FreeType.
|
|
//!
|
|
//! \sa CFontRenderer::GetGlyph, CFontTexture::UpdateSlot
|
|
int GetGlyph(CGlyphBitmap** pGlyph, int* piHoriAdvance, int* piWidth, int* piHeight, AZ::s32& iCharOffsetX, AZ::s32& iCharOffsetY, uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams());
|
|
|
|
void GetMemoryUsage(ICrySizer* pSizer) const
|
|
{
|
|
pSizer->AddObject(m_pSlotList);
|
|
//pSizer->AddContainer(m_pCacheTable);
|
|
pSizer->AddObject(m_pScaleBitmap);
|
|
pSizer->AddObject(m_pFontRenderer);
|
|
}
|
|
|
|
bool GetMonospaced() const { return m_pFontRenderer.GetMonospaced(); }
|
|
|
|
Vec2 GetKerning(uint32_t leftGlyph, uint32_t rightGlyph);
|
|
|
|
float GetAscenderToHeightRatio();
|
|
|
|
private:
|
|
|
|
//! Returns a key for the cache table where the given char is mapped at the given size.
|
|
CryFont::GlyphCache::CCacheTableKey GetCacheSlotKey(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize) const;
|
|
|
|
int CreateSlotList(int iListSize);
|
|
int ReleaseSlotList();
|
|
|
|
CCacheSlotList m_pSlotList;
|
|
CCacheTable m_pCacheTable;
|
|
|
|
int m_iGlyphBitmapWidth;
|
|
int m_iGlyphBitmapHeight;
|
|
|
|
int m_iSmoothMethod;
|
|
int m_iSmoothAmount;
|
|
|
|
CGlyphBitmap* m_pScaleBitmap;
|
|
|
|
CFontRenderer m_pFontRenderer;
|
|
|
|
unsigned int m_dwUsage;
|
|
};
|
|
|
|
#endif // #if !defined(USE_NULLFONT_ALWAYS)
|
|
|
|
#endif // CRYINCLUDE_CRYFONT_GLYPHCACHE_H
|