bonefish + stippi:
Reworked the glyph caching: * It is now glyph index based (a font file has an internal glyph code to index mapping, so that for example the same fallback glyph is used for all unsupported codes). * We do not truncate to uint16 anymore at various places, but support the full 32 bit char codes. * This made it necessary to switch to an OpenHashTable based cache lookup. * In CharacterMap, you can now see that the second Unicode plane does not wrap around anymore. TODO: Remove old entries from the hash table after a while to free up memory. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31780 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -27,6 +27,9 @@
|
|||||||
#include "FontCacheEntry.h"
|
#include "FontCacheEntry.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include <agg_array.h>
|
#include <agg_array.h>
|
||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
@@ -40,88 +43,114 @@ BLocker
|
|||||||
FontCacheEntry::sUsageUpdateLock("FontCacheEntry usage lock");
|
FontCacheEntry::sUsageUpdateLock("FontCacheEntry usage lock");
|
||||||
|
|
||||||
class FontCacheEntry::GlyphCachePool {
|
class FontCacheEntry::GlyphCachePool {
|
||||||
public:
|
public:
|
||||||
enum block_size_e { block_size = 16384-16 };
|
|
||||||
|
|
||||||
GlyphCachePool()
|
GlyphCachePool()
|
||||||
: fAllocator(block_size)
|
|
||||||
{
|
{
|
||||||
memset(fGlyphs, 0, sizeof(fGlyphs));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const GlyphCache* FindGlyph(uint16 glyphCode) const
|
~GlyphCachePool()
|
||||||
{
|
{
|
||||||
unsigned msb = (glyphCode >> 8) & 0xFF;
|
GlyphCache* glyph = fGlyphTable.Clear(true);
|
||||||
if (fGlyphs[msb])
|
while (glyph != NULL) {
|
||||||
return fGlyphs[msb][glyphCode & 0xFF];
|
GlyphCache* next = glyph->fNext;
|
||||||
return 0;
|
delete glyph;
|
||||||
|
glyph = next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GlyphCache* CacheGlyph(uint16 glyphCode, unsigned glyphIndex,
|
status_t Init()
|
||||||
unsigned dataSize, glyph_data_type dataType, const agg::rect_i& bounds,
|
{
|
||||||
|
return fGlyphTable.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
const GlyphCache* FindGlyph(uint32 glyphIndex) const
|
||||||
|
{
|
||||||
|
return fGlyphTable.Lookup(glyphIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlyphCache* CacheGlyph(uint32 glyphIndex,
|
||||||
|
uint32 dataSize, glyph_data_type dataType, const agg::rect_i& bounds,
|
||||||
float advanceX, float advanceY, float insetLeft, float insetRight)
|
float advanceX, float advanceY, float insetLeft, float insetRight)
|
||||||
{
|
{
|
||||||
unsigned msb = (glyphCode >> 8) & 0xFF;
|
GlyphCache* glyph = fGlyphTable.Lookup(glyphIndex);
|
||||||
if (fGlyphs[msb] == 0) {
|
if (glyph != NULL)
|
||||||
fGlyphs[msb]
|
|
||||||
= (GlyphCache**)fAllocator.allocate(sizeof(GlyphCache*) * 256,
|
|
||||||
sizeof(GlyphCache*));
|
|
||||||
memset(fGlyphs[msb], 0, sizeof(GlyphCache*) * 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned lsb = glyphCode & 0xFF;
|
|
||||||
if (fGlyphs[msb][lsb])
|
|
||||||
return NULL; // already exists, do not overwrite
|
|
||||||
|
|
||||||
GlyphCache* glyph
|
|
||||||
= (GlyphCache*)fAllocator.allocate(sizeof(GlyphCache),
|
|
||||||
sizeof(double));
|
|
||||||
|
|
||||||
if (glyph == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
glyph->glyph_index = glyphIndex;
|
glyph = new(std::nothrow) GlyphCache(glyphIndex, dataSize, dataType,
|
||||||
glyph->data = fAllocator.allocate(dataSize);
|
bounds, advanceX, advanceY, insetLeft, insetRight);
|
||||||
glyph->data_size = dataSize;
|
if (glyph == NULL || glyph->data == NULL) {
|
||||||
glyph->data_type = dataType;
|
delete glyph;
|
||||||
glyph->bounds = bounds;
|
return NULL;
|
||||||
glyph->advance_x = advanceX;
|
}
|
||||||
glyph->advance_y = advanceY;
|
|
||||||
glyph->inset_left = insetLeft;
|
|
||||||
glyph->inset_right = insetRight;
|
|
||||||
|
|
||||||
return fGlyphs[msb][lsb] = glyph;
|
// TODO: The HashTable grows without bounds. We should cleanup
|
||||||
|
// older entries from time to time.
|
||||||
|
|
||||||
|
fGlyphTable.Insert(glyph);
|
||||||
|
|
||||||
|
return glyph;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
agg::block_allocator fAllocator;
|
struct GlyphHashTableDefinition {
|
||||||
GlyphCache** fGlyphs[256];
|
typedef uint32 KeyType;
|
||||||
|
typedef GlyphCache ValueType;
|
||||||
|
|
||||||
|
size_t HashKey(uint32 key) const
|
||||||
|
{
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Hash(GlyphCache* value) const
|
||||||
|
{
|
||||||
|
return value->glyph_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compare(uint32 key, GlyphCache* value) const
|
||||||
|
{
|
||||||
|
return value->glyph_index == key;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashTableLink<GlyphCache>* GetLink(GlyphCache* value) const
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef OpenHashTable<GlyphHashTableDefinition> GlyphTable;
|
||||||
|
|
||||||
|
GlyphTable fGlyphTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
// constructor
|
|
||||||
FontCacheEntry::FontCacheEntry()
|
FontCacheEntry::FontCacheEntry()
|
||||||
: MultiLocker("FontCacheEntry lock")
|
:
|
||||||
, Referenceable()
|
MultiLocker("FontCacheEntry lock"),
|
||||||
, fGlyphCache(new GlyphCachePool())
|
Referenceable(),
|
||||||
, fEngine()
|
fGlyphCache(new(std::nothrow) GlyphCachePool()),
|
||||||
, fLastUsedTime(LONGLONG_MIN)
|
fEngine(),
|
||||||
, fUseCounter(0)
|
fLastUsedTime(LONGLONG_MIN),
|
||||||
|
fUseCounter(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
|
||||||
FontCacheEntry::~FontCacheEntry()
|
FontCacheEntry::~FontCacheEntry()
|
||||||
{
|
{
|
||||||
//printf("~FontCacheEntry()\n");
|
//printf("~FontCacheEntry()\n");
|
||||||
delete fGlyphCache;
|
delete fGlyphCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init
|
|
||||||
bool
|
bool
|
||||||
FontCacheEntry::Init(const ServerFont& font)
|
FontCacheEntry::Init(const ServerFont& font)
|
||||||
{
|
{
|
||||||
|
if (fGlyphCache == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
glyph_rendering renderingType = _RenderTypeFor(font);
|
glyph_rendering renderingType = _RenderTypeFor(font);
|
||||||
|
|
||||||
// TODO: encoding from font
|
// TODO: encoding from font
|
||||||
@@ -134,17 +163,24 @@ FontCacheEntry::Init(const ServerFont& font)
|
|||||||
"file %s\n", font.Path());
|
"file %s\n", font.Path());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (fGlyphCache->Init() != B_OK) {
|
||||||
|
fprintf(stderr, "FontCacheEntry::Init() - failed to allocate "
|
||||||
|
"GlyphCache table for font file %s\n", font.Path());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasGlyphs
|
|
||||||
bool
|
bool
|
||||||
FontCacheEntry::HasGlyphs(const char* utf8String, ssize_t length) const
|
FontCacheEntry::HasGlyphs(const char* utf8String, ssize_t length) const
|
||||||
{
|
{
|
||||||
uint32 charCode;
|
uint32 charCode;
|
||||||
const char* start = utf8String;
|
const char* start = utf8String;
|
||||||
while ((charCode = UTF8ToCharCode(&utf8String))) {
|
while ((charCode = UTF8ToCharCode(&utf8String))) {
|
||||||
if (!fGlyphCache->FindGlyph(charCode))
|
uint32 glyphIndex = fEngine.GlyphIndexForGlyphCode(charCode);
|
||||||
|
if (!fGlyphCache->FindGlyph(glyphIndex))
|
||||||
return false;
|
return false;
|
||||||
if (utf8String - start + 1 > length)
|
if (utf8String - start + 1 > length)
|
||||||
break;
|
break;
|
||||||
@@ -152,30 +188,31 @@ FontCacheEntry::HasGlyphs(const char* utf8String, ssize_t length) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Glyph
|
|
||||||
const GlyphCache*
|
const GlyphCache*
|
||||||
FontCacheEntry::Glyph(uint16 glyphCode)
|
FontCacheEntry::Glyph(uint32 glyphCode)
|
||||||
{
|
{
|
||||||
const GlyphCache* glyph = fGlyphCache->FindGlyph(glyphCode);
|
uint32 glyphIndex = fEngine.GlyphIndexForGlyphCode(glyphCode);
|
||||||
|
const GlyphCache* glyph = fGlyphCache->FindGlyph(glyphIndex);
|
||||||
if (glyph) {
|
if (glyph) {
|
||||||
return glyph;
|
return glyph;
|
||||||
} else {
|
} else {
|
||||||
if (fEngine.PrepareGlyph(glyphCode)) {
|
if (fEngine.PrepareGlyph(glyphIndex)) {
|
||||||
glyph = fGlyphCache->CacheGlyph(glyphCode,
|
glyph = fGlyphCache->CacheGlyph(glyphIndex,
|
||||||
fEngine.GlyphIndex(), fEngine.DataSize(),
|
fEngine.DataSize(), fEngine.DataType(), fEngine.Bounds(),
|
||||||
fEngine.DataType(), fEngine.Bounds(),
|
|
||||||
fEngine.AdvanceX(), fEngine.AdvanceY(),
|
fEngine.AdvanceX(), fEngine.AdvanceY(),
|
||||||
fEngine.InsetLeft(), fEngine.InsetRight());
|
fEngine.InsetLeft(), fEngine.InsetRight());
|
||||||
|
|
||||||
fEngine.WriteGlyphTo(glyph->data);
|
if (glyph != NULL)
|
||||||
|
fEngine.WriteGlyphTo(glyph->data);
|
||||||
|
|
||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitAdaptors
|
|
||||||
void
|
void
|
||||||
FontCacheEntry::InitAdaptors(const GlyphCache* glyph,
|
FontCacheEntry::InitAdaptors(const GlyphCache* glyph,
|
||||||
double x, double y, GlyphMonoAdapter& monoAdapter,
|
double x, double y, GlyphMonoAdapter& monoAdapter,
|
||||||
@@ -207,15 +244,15 @@ FontCacheEntry::InitAdaptors(const GlyphCache* glyph,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetKerning
|
|
||||||
bool
|
bool
|
||||||
FontCacheEntry::GetKerning(uint16 glyphCode1, uint16 glyphCode2,
|
FontCacheEntry::GetKerning(uint32 glyphCode1, uint32 glyphCode2,
|
||||||
double* x, double* y)
|
double* x, double* y)
|
||||||
{
|
{
|
||||||
return fEngine.GetKerning(glyphCode1, glyphCode2, x, y);
|
return fEngine.GetKerning(glyphCode1, glyphCode2, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateSignature
|
|
||||||
/*static*/ void
|
/*static*/ void
|
||||||
FontCacheEntry::GenerateSignature(char* signature, size_t signatureSize,
|
FontCacheEntry::GenerateSignature(char* signature, size_t signatureSize,
|
||||||
const ServerFont& font)
|
const ServerFont& font)
|
||||||
@@ -232,7 +269,7 @@ FontCacheEntry::GenerateSignature(char* signature, size_t signatureSize,
|
|||||||
font.Face(), int(renderingType), font.Size(), hinting, averageWeight);
|
font.Face(), int(renderingType), font.Size(), hinting, averageWeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUsage
|
|
||||||
void
|
void
|
||||||
FontCacheEntry::UpdateUsage()
|
FontCacheEntry::UpdateUsage()
|
||||||
{
|
{
|
||||||
@@ -248,7 +285,6 @@ FontCacheEntry::UpdateUsage()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _RenderTypeFor
|
|
||||||
/*static*/ glyph_rendering
|
/*static*/ glyph_rendering
|
||||||
FontCacheEntry::_RenderTypeFor(const ServerFont& font)
|
FontCacheEntry::_RenderTypeFor(const ServerFont& font)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
#include <agg_conv_contour.h>
|
#include <agg_conv_contour.h>
|
||||||
#include <agg_conv_transform.h>
|
#include <agg_conv_transform.h>
|
||||||
|
|
||||||
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
#include "ServerFont.h"
|
#include "ServerFont.h"
|
||||||
#include "FontEngine.h"
|
#include "FontEngine.h"
|
||||||
#include "MultiLocker.h"
|
#include "MultiLocker.h"
|
||||||
@@ -40,10 +42,31 @@
|
|||||||
#include "Transformable.h"
|
#include "Transformable.h"
|
||||||
|
|
||||||
|
|
||||||
struct GlyphCache {
|
struct GlyphCache : public HashTableLink<GlyphCache> {
|
||||||
unsigned glyph_index;
|
GlyphCache(uint32 glyphIndex, uint32 dataSize, glyph_data_type dataType,
|
||||||
|
const agg::rect_i& bounds, float advanceX, float advanceY,
|
||||||
|
float insetLeft, float insetRight)
|
||||||
|
:
|
||||||
|
glyph_index(glyphIndex),
|
||||||
|
data((uint8*)malloc(dataSize)),
|
||||||
|
data_size(dataSize),
|
||||||
|
data_type(dataType),
|
||||||
|
bounds(bounds),
|
||||||
|
advance_x(advanceX),
|
||||||
|
advance_y(advanceY),
|
||||||
|
inset_left(insetLeft),
|
||||||
|
inset_right(insetRight)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~GlyphCache()
|
||||||
|
{
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 glyph_index;
|
||||||
uint8* data;
|
uint8* data;
|
||||||
unsigned data_size;
|
uint32 data_size;
|
||||||
glyph_data_type data_type;
|
glyph_data_type data_type;
|
||||||
agg::rect_i bounds;
|
agg::rect_i bounds;
|
||||||
float advance_x;
|
float advance_x;
|
||||||
@@ -80,7 +103,7 @@ class FontCacheEntry : public MultiLocker, public Referenceable {
|
|||||||
bool HasGlyphs(const char* utf8String,
|
bool HasGlyphs(const char* utf8String,
|
||||||
ssize_t glyphCount) const;
|
ssize_t glyphCount) const;
|
||||||
|
|
||||||
const GlyphCache* Glyph(uint16 glyphCode);
|
const GlyphCache* Glyph(uint32 glyphCode);
|
||||||
|
|
||||||
void InitAdaptors(const GlyphCache* glyph,
|
void InitAdaptors(const GlyphCache* glyph,
|
||||||
double x, double y,
|
double x, double y,
|
||||||
@@ -89,8 +112,8 @@ class FontCacheEntry : public MultiLocker, public Referenceable {
|
|||||||
GlyphPathAdapter& pathAdapter,
|
GlyphPathAdapter& pathAdapter,
|
||||||
double scale = 1.0);
|
double scale = 1.0);
|
||||||
|
|
||||||
bool GetKerning(uint16 glyphCode1,
|
bool GetKerning(uint32 glyphCode1,
|
||||||
uint16 glyphCode2, double* x, double* y);
|
uint32 glyphCode2, double* x, double* y);
|
||||||
|
|
||||||
static void GenerateSignature(char* signature,
|
static void GenerateSignature(char* signature,
|
||||||
size_t signatureSize,
|
size_t signatureSize,
|
||||||
|
|||||||
@@ -42,14 +42,13 @@
|
|||||||
static const bool kFlipY = true;
|
static const bool kFlipY = true;
|
||||||
|
|
||||||
|
|
||||||
// int26p6_to_dbl
|
|
||||||
static inline double
|
static inline double
|
||||||
int26p6_to_dbl(int p)
|
int26p6_to_dbl(int p)
|
||||||
{
|
{
|
||||||
return double(p) / 64.0;
|
return double(p) / 64.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbl_to_int26p6
|
|
||||||
static inline int
|
static inline int
|
||||||
dbl_to_int26p6(double p)
|
dbl_to_int26p6(double p)
|
||||||
{
|
{
|
||||||
@@ -57,7 +56,6 @@ dbl_to_int26p6(double p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// decompose_ft_outline
|
|
||||||
template<class PathStorage>
|
template<class PathStorage>
|
||||||
bool
|
bool
|
||||||
decompose_ft_outline(const FT_Outline& outline, bool flip_y, PathStorage& path)
|
decompose_ft_outline(const FT_Outline& outline, bool flip_y, PathStorage& path)
|
||||||
@@ -289,7 +287,6 @@ decompose_ft_outline(const FT_Outline& outline, bool flip_y, PathStorage& path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// decompose_ft_bitmap_mono
|
|
||||||
template<class Scanline, class ScanlineStorage>
|
template<class Scanline, class ScanlineStorage>
|
||||||
void
|
void
|
||||||
decompose_ft_bitmap_mono(const FT_Bitmap& bitmap, int x, int y,
|
decompose_ft_bitmap_mono(const FT_Bitmap& bitmap, int x, int y,
|
||||||
@@ -321,7 +318,6 @@ decompose_ft_bitmap_mono(const FT_Bitmap& bitmap, int x, int y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// decompose_ft_bitmap_gray8
|
|
||||||
template<class Scanline, class ScanlineStorage>
|
template<class Scanline, class ScanlineStorage>
|
||||||
void
|
void
|
||||||
decompose_ft_bitmap_gray8(const FT_Bitmap& bitmap, int x, int y,
|
decompose_ft_bitmap_gray8(const FT_Bitmap& bitmap, int x, int y,
|
||||||
@@ -365,7 +361,6 @@ decompose_ft_bitmap_gray8(const FT_Bitmap& bitmap, int x, int y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// decompose_ft_bitmap_subpix
|
|
||||||
template<class Scanline, class ScanlineStorage>
|
template<class Scanline, class ScanlineStorage>
|
||||||
void
|
void
|
||||||
decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y,
|
decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y,
|
||||||
@@ -557,36 +552,36 @@ decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
FontEngine::FontEngine()
|
FontEngine::FontEngine()
|
||||||
: fLastError(0)
|
:
|
||||||
, fLibraryInitialized(false)
|
fLastError(0),
|
||||||
, fLibrary(0)
|
fLibraryInitialized(false),
|
||||||
, fFace(NULL)
|
fLibrary(0),
|
||||||
|
fFace(NULL),
|
||||||
|
|
||||||
, fGlyphRendering(glyph_ren_native_gray8)
|
fGlyphRendering(glyph_ren_native_gray8),
|
||||||
, fHinting(true)
|
fHinting(true),
|
||||||
|
|
||||||
, fGlyphIndex(0)
|
fDataSize(0),
|
||||||
, fDataSize(0)
|
fDataType(glyph_data_invalid),
|
||||||
, fDataType(glyph_data_invalid)
|
fBounds(1, 1, 0, 0),
|
||||||
, fBounds(1, 1, 0, 0)
|
fAdvanceX(0.0),
|
||||||
, fAdvanceX(0.0)
|
fAdvanceY(0.0),
|
||||||
, fAdvanceY(0.0)
|
fInsetLeft(0.0),
|
||||||
, fInsetLeft(0.0)
|
fInsetRight(0.0),
|
||||||
, fInsetRight(0.0)
|
|
||||||
|
|
||||||
, fPath()
|
fPath(),
|
||||||
, fCurves(fPath)
|
fCurves(fPath),
|
||||||
, fScanlineAA()
|
fScanlineAA(),
|
||||||
, fScanlineBin()
|
fScanlineBin(),
|
||||||
, fScanlineSubpix()
|
fScanlineSubpix(),
|
||||||
, fScanlineStorageAA()
|
fScanlineStorageAA(),
|
||||||
, fScanlineStorageBin()
|
fScanlineStorageBin(),
|
||||||
, fScanlineStorageSubpix()
|
fScanlineStorageSubpix()
|
||||||
{
|
{
|
||||||
fCurves.approximation_scale(4.0);
|
fCurves.approximation_scale(4.0);
|
||||||
|
|
||||||
@@ -596,7 +591,6 @@ FontEngine::FontEngine()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
FontEngine::~FontEngine()
|
FontEngine::~FontEngine()
|
||||||
{
|
{
|
||||||
FT_Done_Face(fFace);
|
FT_Done_Face(fFace);
|
||||||
@@ -606,7 +600,6 @@ FontEngine::~FontEngine()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// CountFaces
|
|
||||||
unsigned
|
unsigned
|
||||||
FontEngine::CountFaces() const
|
FontEngine::CountFaces() const
|
||||||
{
|
{
|
||||||
@@ -617,13 +610,19 @@ FontEngine::CountFaces() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// PrepareGlyph
|
uint32
|
||||||
bool
|
FontEngine::GlyphIndexForGlyphCode(uint32 glyphCode) const
|
||||||
FontEngine::PrepareGlyph(unsigned glyphCode)
|
|
||||||
{
|
{
|
||||||
fGlyphIndex = FT_Get_Char_Index(fFace, glyphCode);
|
FT_Get_Char_Index(fFace, glyphCode);
|
||||||
fLastError = FT_Load_Glyph(fFace, fGlyphIndex,
|
}
|
||||||
(fHinting ? (FT_LOAD_DEFAULT | FT_LOAD_TARGET_LCD) : FT_LOAD_NO_HINTING));
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FontEngine::PrepareGlyph(uint32 glyphIndex)
|
||||||
|
{
|
||||||
|
fLastError = FT_Load_Glyph(fFace, glyphIndex,
|
||||||
|
(fHinting ? (FT_LOAD_DEFAULT | FT_LOAD_TARGET_LCD)
|
||||||
|
: FT_LOAD_NO_HINTING));
|
||||||
|
|
||||||
if (fLastError != 0)
|
if (fLastError != 0)
|
||||||
return false;
|
return false;
|
||||||
@@ -740,8 +739,7 @@ FontEngine::WriteGlyphTo(uint8* data) const
|
|||||||
|
|
||||||
// GetKerning
|
// GetKerning
|
||||||
bool
|
bool
|
||||||
FontEngine::GetKerning(unsigned first, unsigned second,
|
FontEngine::GetKerning(uint32 first, uint32 second, double* x, double* y)
|
||||||
double* x, double* y)
|
|
||||||
{
|
{
|
||||||
if (fFace && first && second && FT_HAS_KERNING(fFace)) {
|
if (fFace && first && second && FT_HAS_KERNING(fFace)) {
|
||||||
FT_Vector delta;
|
FT_Vector delta;
|
||||||
|
|||||||
@@ -92,11 +92,10 @@ class FontEngine {
|
|||||||
{ return fHinting; }
|
{ return fHinting; }
|
||||||
|
|
||||||
|
|
||||||
bool PrepareGlyph(unsigned glyphCode);
|
uint32 GlyphIndexForGlyphCode(uint32 glyphCode) const;
|
||||||
|
bool PrepareGlyph(uint32 glyphIndex);
|
||||||
|
|
||||||
unsigned GlyphIndex() const
|
uint32 DataSize() const
|
||||||
{ return fGlyphIndex; }
|
|
||||||
unsigned DataSize() const
|
|
||||||
{ return fDataSize; }
|
{ return fDataSize; }
|
||||||
glyph_data_type DataType() const
|
glyph_data_type DataType() const
|
||||||
{ return fDataType; }
|
{ return fDataType; }
|
||||||
@@ -114,7 +113,7 @@ class FontEngine {
|
|||||||
void WriteGlyphTo(uint8* data) const;
|
void WriteGlyphTo(uint8* data) const;
|
||||||
|
|
||||||
|
|
||||||
bool GetKerning(unsigned first, unsigned second,
|
bool GetKerning(uint32 first, uint32 second,
|
||||||
double* x, double* y);
|
double* x, double* y);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -132,8 +131,7 @@ class FontEngine {
|
|||||||
|
|
||||||
// members needed to generate individual glyphs according
|
// members needed to generate individual glyphs according
|
||||||
// to glyph rendering type
|
// to glyph rendering type
|
||||||
unsigned fGlyphIndex;
|
uint32 fDataSize;
|
||||||
unsigned fDataSize;
|
|
||||||
glyph_data_type fDataType;
|
glyph_data_type fDataType;
|
||||||
agg::rect_i fBounds;
|
agg::rect_i fBounds;
|
||||||
double fAdvanceX;
|
double fAdvanceX;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
SubDir HAIKU_TOP src servers app drawing ;
|
SubDir HAIKU_TOP src servers app drawing ;
|
||||||
|
|
||||||
UseLibraryHeaders agg ;
|
UseLibraryHeaders agg ;
|
||||||
UsePrivateHeaders app graphics interface shared ;
|
UsePrivateHeaders app graphics interface kernel shared ;
|
||||||
UsePrivateHeaders [ FDirName graphics common ] ;
|
UsePrivateHeaders [ FDirName graphics common ] ;
|
||||||
UsePrivateSystemHeaders ;
|
UsePrivateSystemHeaders ;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
|
|||||||
AddSubDirSupportedPlatforms libbe_test ;
|
AddSubDirSupportedPlatforms libbe_test ;
|
||||||
|
|
||||||
UseLibraryHeaders agg ;
|
UseLibraryHeaders agg ;
|
||||||
UsePrivateHeaders app graphics interface shared ;
|
UsePrivateHeaders app graphics interface kernel shared ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src servers app ] ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter drawing_modes ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter drawing_modes ] ;
|
||||||
|
|||||||
Reference in New Issue
Block a user