* fix the mixup of charCount (glyphs) versus bytes. The new font cache
implementation takes the byte count, even though it looks like this is less efficient when the glyph count is already known (I tested to optimize it away but it was not faster) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21891 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1637,7 +1637,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
bool hasArray[numChars];
|
bool hasArray[numChars];
|
||||||
status = font.GetHasGlyphs(charArray, numChars, hasArray);
|
status = font.GetHasGlyphs(charArray, numBytes, hasArray);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
fLink.Attach(hasArray, sizeof(hasArray));
|
fLink.Attach(hasArray, sizeof(hasArray));
|
||||||
@@ -1676,7 +1676,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
edge_info edgeArray[numChars];
|
edge_info edgeArray[numChars];
|
||||||
status = font.GetEdges(charArray, numChars, edgeArray);
|
status = font.GetEdges(charArray, numBytes, edgeArray);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
fLink.Attach(edgeArray, sizeof(edgeArray));
|
fLink.Attach(edgeArray, sizeof(edgeArray));
|
||||||
@@ -1747,7 +1747,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
if (wantsOffsets)
|
if (wantsOffsets)
|
||||||
offsets = new (nothrow) BPoint[numChars];
|
offsets = new (nothrow) BPoint[numChars];
|
||||||
|
|
||||||
status = font.GetEscapements(charArray, numChars, delta,
|
status = font.GetEscapements(charArray, numBytes, delta,
|
||||||
escapements, offsets);
|
escapements, offsets);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
@@ -1829,7 +1829,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
font.SetRotation(rotation);
|
font.SetRotation(rotation);
|
||||||
font.SetFlags(flags);
|
font.SetFlags(flags);
|
||||||
|
|
||||||
status = font.GetEscapements(charArray, numChars, delta,
|
status = font.GetEscapements(charArray, numBytes, delta,
|
||||||
escapements);
|
escapements);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
@@ -1917,7 +1917,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
font.SetFlags(flags);
|
font.SetFlags(flags);
|
||||||
|
|
||||||
// TODO implement for real
|
// TODO implement for real
|
||||||
if (font.GetBoundingBoxes(charArray, numChars,
|
if (font.GetBoundingBoxes(charArray, numBytes,
|
||||||
rectArray, string_escapement, mode, delta,
|
rectArray, string_escapement, mode, delta,
|
||||||
code == AS_GET_BOUNDINGBOXES_STRING) == B_OK) {
|
code == AS_GET_BOUNDINGBOXES_STRING) == B_OK) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
|
|||||||
@@ -390,23 +390,45 @@ ServerFont::GetGlyphShapes(const char charArray[], int32 numChars,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class HasGlyphsConsumer {
|
||||||
|
public:
|
||||||
|
HasGlyphsConsumer(bool* hasArray)
|
||||||
|
: fHasArray(hasArray)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Start() {}
|
||||||
|
void Finish(double x, double y) {}
|
||||||
|
void ConsumeEmptyGlyph(int32 index, uint32 charCode, double x, double y)
|
||||||
|
{
|
||||||
|
fHasArray[index] = false;
|
||||||
|
}
|
||||||
|
bool ConsumeGlyph(int32 index, uint32 charCode, const GlyphCache* glyph,
|
||||||
|
FontCacheEntry* entry, double x, double y)
|
||||||
|
{
|
||||||
|
fHasArray[index] = glyph->glyph_index >= 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool* fHasArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ServerFont::GetHasGlyphs(const char charArray[], int32 numChars,
|
ServerFont::GetHasGlyphs(const char* string, int32 numBytes,
|
||||||
bool hasArray[]) const
|
bool* hasArray) const
|
||||||
{
|
{
|
||||||
if (!charArray || numChars <= 0 || !hasArray)
|
if (!string || numBytes <= 0 || !hasArray)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
FT_Face face = GetTransformedFace(false, false);
|
bool kerning = true; // TODO make this a property?
|
||||||
if (!face)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
const char *string = charArray;
|
HasGlyphsConsumer consumer(hasArray);
|
||||||
for (int i = 0; i < numChars; i++)
|
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||||
hasArray[i] = FT_Get_Char_Index(face, UTF8ToCharCode(&string)) > 0;
|
NULL, kerning, fSpacing))
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
PutTransformedFace(face);
|
return B_ERROR;
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -439,16 +461,16 @@ class EdgesConsumer {
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ServerFont::GetEdges(const char* string, int32 numChars,
|
ServerFont::GetEdges(const char* string, int32 numBytes,
|
||||||
edge_info* edges) const
|
edge_info* edges) const
|
||||||
{
|
{
|
||||||
if (!string || numChars <= 0 || !edges)
|
if (!string || numBytes <= 0 || !edges)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
bool kerning = true; // TODO make this a property?
|
bool kerning = true; // TODO make this a property?
|
||||||
|
|
||||||
EdgesConsumer consumer(edges, fSize);
|
EdgesConsumer consumer(edges, fSize);
|
||||||
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numChars,
|
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||||
NULL, kerning, fSpacing))
|
NULL, kerning, fSpacing))
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
@@ -516,17 +538,17 @@ class BPointEscapementConsumer {
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ServerFont::GetEscapements(const char* string, int32 numChars,
|
ServerFont::GetEscapements(const char* string, int32 numBytes,
|
||||||
escapement_delta delta, BPoint escapementArray[],
|
escapement_delta delta, BPoint escapementArray[],
|
||||||
BPoint offsetArray[]) const
|
BPoint offsetArray[]) const
|
||||||
{
|
{
|
||||||
if (!string || numChars <= 0 || !escapementArray)
|
if (!string || numBytes <= 0 || !escapementArray)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
bool kerning = true; // TODO make this a property?
|
bool kerning = true; // TODO make this a property?
|
||||||
|
|
||||||
BPointEscapementConsumer consumer(escapementArray, offsetArray, fSize);
|
BPointEscapementConsumer consumer(escapementArray, offsetArray, fSize);
|
||||||
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numChars,
|
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||||
&delta, kerning, fSpacing))
|
&delta, kerning, fSpacing))
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
@@ -562,16 +584,16 @@ class WidthEscapementConsumer {
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ServerFont::GetEscapements(const char* string, int32 numChars,
|
ServerFont::GetEscapements(const char* string, int32 numBytes,
|
||||||
escapement_delta delta, float widthArray[]) const
|
escapement_delta delta, float widthArray[]) const
|
||||||
{
|
{
|
||||||
if (!string || numChars <= 0 || !widthArray)
|
if (!string || numBytes <= 0 || !widthArray)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
bool kerning = true; // TODO make this a property?
|
bool kerning = true; // TODO make this a property?
|
||||||
|
|
||||||
WidthEscapementConsumer consumer(widthArray, fSize);
|
WidthEscapementConsumer consumer(widthArray, fSize);
|
||||||
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numChars,
|
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||||
&delta, kerning, fSpacing))
|
&delta, kerning, fSpacing))
|
||||||
return B_OK;
|
return B_OK;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -666,12 +688,12 @@ class BoundingBoxConsumer {
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ServerFont::GetBoundingBoxes(const char* string, int32 numChars,
|
ServerFont::GetBoundingBoxes(const char* string, int32 numBytes,
|
||||||
BRect rectArray[], bool stringEscapement, font_metric_mode mode,
|
BRect rectArray[], bool stringEscapement, font_metric_mode mode,
|
||||||
escapement_delta delta, bool asString)
|
escapement_delta delta, bool asString)
|
||||||
{
|
{
|
||||||
// TODO: The font_metric_mode is not used
|
// TODO: The font_metric_mode is not used
|
||||||
if (!string || numChars <= 0 || !rectArray)
|
if (!string || numBytes <= 0 || !rectArray)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
bool kerning = true; // TODO make this a property?
|
bool kerning = true; // TODO make this a property?
|
||||||
@@ -679,7 +701,7 @@ ServerFont::GetBoundingBoxes(const char* string, int32 numChars,
|
|||||||
Transformable transform(EmbeddedTransformation());
|
Transformable transform(EmbeddedTransformation());
|
||||||
|
|
||||||
BoundingBoxConsumer consumer(transform, rectArray, asString);
|
BoundingBoxConsumer consumer(transform, rectArray, asString);
|
||||||
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numChars,
|
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||||
stringEscapement ? &delta : NULL, kerning, fSpacing))
|
stringEscapement ? &delta : NULL, kerning, fSpacing))
|
||||||
return B_OK;
|
return B_OK;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -700,12 +722,12 @@ ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[],
|
|||||||
Transformable transform(EmbeddedTransformation());
|
Transformable transform(EmbeddedTransformation());
|
||||||
|
|
||||||
for (int32 i = 0; i < numStrings; i++) {
|
for (int32 i = 0; i < numStrings; i++) {
|
||||||
int32 numChars = lengthArray[i];
|
int32 numBytes = lengthArray[i];
|
||||||
const char* string = charArray[i];
|
const char* string = charArray[i];
|
||||||
escapement_delta delta = deltaArray[i];
|
escapement_delta delta = deltaArray[i];
|
||||||
|
|
||||||
BoundingBoxConsumer consumer(transform, NULL, true);
|
BoundingBoxConsumer consumer(transform, NULL, true);
|
||||||
if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numChars,
|
if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||||
&delta, kerning, fSpacing))
|
&delta, kerning, fSpacing))
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -731,16 +753,16 @@ class StringWidthConsumer {
|
|||||||
|
|
||||||
|
|
||||||
float
|
float
|
||||||
ServerFont::StringWidth(const char *string, int32 numChars,
|
ServerFont::StringWidth(const char *string, int32 numBytes,
|
||||||
const escapement_delta* deltaArray) const
|
const escapement_delta* deltaArray) const
|
||||||
{
|
{
|
||||||
if (!string || numChars <= 0)
|
if (!string || numBytes <= 0)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
bool kerning = true; // TODO make this a property?
|
bool kerning = true; // TODO make this a property?
|
||||||
|
|
||||||
StringWidthConsumer consumer;
|
StringWidthConsumer consumer;
|
||||||
if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numChars,
|
if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||||
deltaArray, kerning, fSpacing))
|
deltaArray, kerning, fSpacing))
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
@@ -791,7 +813,7 @@ ServerFont::TruncateString(BString* inOut, uint32 mode, float width) const
|
|||||||
// get the escapement of each glyph in font units
|
// get the escapement of each glyph in font units
|
||||||
float *escapementArray = new float[numChars];
|
float *escapementArray = new float[numChars];
|
||||||
static escapement_delta delta = (escapement_delta){ 0.0, 0.0 };
|
static escapement_delta delta = (escapement_delta){ 0.0, 0.0 };
|
||||||
if (GetEscapements(string, numChars, delta, escapementArray) == B_OK) {
|
if (GetEscapements(string, length, delta, escapementArray) == B_OK) {
|
||||||
truncate_string(string, mode, width, result, escapementArray, fSize,
|
truncate_string(string, mode, width, result, escapementArray, fSize,
|
||||||
ellipsisWidth, length, numChars);
|
ellipsisWidth, length, numChars);
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ class ServerFont {
|
|||||||
{ return fDirection; }
|
{ return fDirection; }
|
||||||
uint32 Encoding() const
|
uint32 Encoding() const
|
||||||
{ return fEncoding; }
|
{ return fEncoding; }
|
||||||
edge_info Edges() const
|
|
||||||
{ return fEdges; }
|
|
||||||
uint32 Flags() const
|
uint32 Flags() const
|
||||||
{ return fFlags; }
|
{ return fFlags; }
|
||||||
uint32 Spacing() const
|
uint32 Spacing() const
|
||||||
@@ -81,8 +79,6 @@ class ServerFont {
|
|||||||
|
|
||||||
void SetDirection(font_direction dir)
|
void SetDirection(font_direction dir)
|
||||||
{ fDirection = dir; }
|
{ fDirection = dir; }
|
||||||
void SetEdges(edge_info info)
|
|
||||||
{ fEdges = info; }
|
|
||||||
void SetEncoding(uint32 encoding)
|
void SetEncoding(uint32 encoding)
|
||||||
{ fEncoding = encoding; }
|
{ fEncoding = encoding; }
|
||||||
void SetFlags(uint32 value)
|
void SetFlags(uint32 value)
|
||||||
@@ -123,22 +119,22 @@ class ServerFont {
|
|||||||
int32 numChars, BShape *shapeArray[]) const;
|
int32 numChars, BShape *shapeArray[]) const;
|
||||||
|
|
||||||
status_t GetHasGlyphs(const char charArray[],
|
status_t GetHasGlyphs(const char charArray[],
|
||||||
int32 numChars, bool hasArray[]) const;
|
int32 numBytes, bool hasArray[]) const;
|
||||||
|
|
||||||
status_t GetEdges(const char charArray[], int32 numChars,
|
status_t GetEdges(const char charArray[], int32 numBytes,
|
||||||
edge_info edgeArray[]) const;
|
edge_info edgeArray[]) const;
|
||||||
|
|
||||||
status_t GetEscapements(const char charArray[],
|
status_t GetEscapements(const char charArray[],
|
||||||
int32 numChars, escapement_delta delta,
|
int32 numBytes, escapement_delta delta,
|
||||||
BPoint escapementArray[],
|
BPoint escapementArray[],
|
||||||
BPoint offsetArray[]) const;
|
BPoint offsetArray[]) const;
|
||||||
|
|
||||||
status_t GetEscapements(const char charArray[],
|
status_t GetEscapements(const char charArray[],
|
||||||
int32 numChars, escapement_delta delta,
|
int32 numBytes, escapement_delta delta,
|
||||||
float widthArray[]) const;
|
float widthArray[]) const;
|
||||||
|
|
||||||
status_t GetBoundingBoxes(const char charArray[],
|
status_t GetBoundingBoxes(const char charArray[],
|
||||||
int32 numChars, BRect rectArray[],
|
int32 numBytes, BRect rectArray[],
|
||||||
bool stringEscapement,
|
bool stringEscapement,
|
||||||
font_metric_mode mode,
|
font_metric_mode mode,
|
||||||
escapement_delta delta,
|
escapement_delta delta,
|
||||||
@@ -150,14 +146,14 @@ class ServerFont {
|
|||||||
escapement_delta deltaArray[]);
|
escapement_delta deltaArray[]);
|
||||||
|
|
||||||
float StringWidth(const char *string,
|
float StringWidth(const char *string,
|
||||||
int32 numChars,
|
int32 numBytes,
|
||||||
const escapement_delta* delta = NULL) const;
|
const escapement_delta* delta = NULL) const;
|
||||||
|
|
||||||
bool Lock() const { return fStyle->Lock(); }
|
bool Lock() const { return fStyle->Lock(); }
|
||||||
void Unlock() const { fStyle->Unlock(); }
|
void Unlock() const { fStyle->Unlock(); }
|
||||||
|
|
||||||
FT_Face GetFTFace() const
|
// FT_Face GetFTFace() const
|
||||||
{ return fStyle->FreeTypeFace(); };
|
// { return fStyle->FreeTypeFace(); };
|
||||||
|
|
||||||
BRect BoundingBox();
|
BRect BoundingBox();
|
||||||
void GetHeight(font_height& height) const;
|
void GetHeight(font_height& height) const;
|
||||||
@@ -172,7 +168,6 @@ protected:
|
|||||||
friend class FontStyle;
|
friend class FontStyle;
|
||||||
|
|
||||||
FontStyle* fStyle;
|
FontStyle* fStyle;
|
||||||
edge_info fEdges;
|
|
||||||
float fSize;
|
float fSize;
|
||||||
float fRotation;
|
float fRotation;
|
||||||
float fShear;
|
float fShear;
|
||||||
|
|||||||
Reference in New Issue
Block a user