* 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:
Stephan Aßmus
2007-08-11 13:34:09 +00:00
parent b595496d03
commit aadc09c665
3 changed files with 64 additions and 47 deletions
+5 -5
View File
@@ -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);
+51 -29
View File
@@ -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);
+8 -13
View File
@@ -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;