Use FTFace() function to get the face instead of always creating a new one.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12007 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2005-03-25 21:11:46 +00:00
parent 6d495dfc26
commit d31e3b8e27
+59 -105
View File
@@ -1949,29 +1949,21 @@ void DisplayDriverImpl::DrawString(const char *string, const int32 &length, cons
BRect intersection(pt.x, pt.x, pt.y, pt.y); BRect intersection(pt.x, pt.x, pt.y, pt.y);
intersection.top -= d->font.Size() * 1.5; intersection.top -= d->font.Size() * 1.5;
intersection.right += d->font.Size() * 1.5 * length; intersection.right += d->font.Size() * 1.5 * length;
if (fCursorHandler.IntersectsCursor(intersection)) if (fCursorHandler.IntersectsCursor(intersection))
fCursorHandler.DriverHide(); fCursorHandler.DriverHide();
BPoint point(pt); BPoint point(pt);
const ServerFont *font = &(d->font); const ServerFont *font = &(d->font);
FT_Face face;
FT_GlyphSlot slot;
FT_Matrix rmatrix,smatrix;
FT_UInt glyph_index=0, previous=0;
FT_Vector pen,delta,space,nonspace;
int16 error=0;
int32 strlength,i;
Angle rotation(font->Rotation()), shear(font->Shear());
bool antialias = true; bool antialias = true;
if (font->Size() < 18 && font->Flags() & B_DISABLE_ANTIALIASING)
if(font->Size()<18 && (font->Flags()& B_DISABLE_ANTIALIASING==1))
antialias = false; antialias = false;
// Originally, I thought to do this shear checking here, but it really should be // Originally, I thought to do this shear checking here, but it really should be
// done in BFont::SetShear() // done in BFont::SetShear()
Angle shear(font->Shear());
if (font->Shear() != 90) {
float shearangle = shear.Value(); float shearangle = shear.Value();
if (shearangle > 135) if (shearangle > 135)
shearangle = 135; shearangle = 135;
@@ -1982,39 +1974,40 @@ void DisplayDriverImpl::DrawString(const char *string, const int32 &length, cons
shear = 90 + ((180 - shearangle) * 2); shear = 90 + ((180 - shearangle) * 2);
else else
shear = 90 - (90 - shearangle) * 2; shear = 90 - (90 - shearangle) * 2;
}
error=FT_New_Face(ftlib, font->GetPath(), 0, &face); FT_Face face = font->GetFTFace();
if(error) if (!face) {
{
Unlock(); Unlock();
return; return;
} }
slot=face->glyph; uint16 error = FT_Set_Char_Size(face, 0, int32(font->Size()) * 64, 72, 72);
if (error) {
bool use_kerning=FT_HAS_KERNING(face) && font->Spacing()==B_STRING_SPACING;
error=FT_Set_Char_Size(face, 0,int32(font->Size())*64,72,72);
if(error)
{
Unlock(); Unlock();
return; return;
} }
// if we do any transformation, we do a call to FT_Set_Transform() here bool use_kerning = font->HasKerning() && font->Spacing() == B_STRING_SPACING;
FT_Vector space, nonspace;
Angle rotation(font->Rotation());
// First, rotate // First, rotate
FT_Matrix rmatrix;
rmatrix.xx = (FT_Fixed)( rotation.Cosine()*0x10000); rmatrix.xx = (FT_Fixed)( rotation.Cosine()*0x10000);
rmatrix.xy = (FT_Fixed)(-rotation.Sine()*0x10000); rmatrix.xy = (FT_Fixed)(-rotation.Sine()*0x10000);
rmatrix.yx = (FT_Fixed)( rotation.Sine()*0x10000); rmatrix.yx = (FT_Fixed)( rotation.Sine()*0x10000);
rmatrix.yy = (FT_Fixed)( rotation.Cosine()*0x10000); rmatrix.yy = (FT_Fixed)( rotation.Cosine()*0x10000);
// Next, shear // Next, shear
FT_Matrix smatrix;
smatrix.xx = (FT_Fixed)(0x10000); smatrix.xx = (FT_Fixed)(0x10000);
smatrix.xy = (FT_Fixed)(-shear.Cosine()*0x10000); smatrix.xy = (FT_Fixed)(-shear.Cosine()*0x10000);
smatrix.yx = (FT_Fixed)(0); smatrix.yx = (FT_Fixed)(0);
smatrix.yy = (FT_Fixed)(0x10000); smatrix.yy = (FT_Fixed)(0x10000);
// Multiply togheter
FT_Matrix_Multiply(&rmatrix, &smatrix); FT_Matrix_Multiply(&rmatrix, &smatrix);
// Set up the increment value for escapement padding // Set up the increment value for escapement padding
@@ -2024,53 +2017,44 @@ void DisplayDriverImpl::DrawString(const char *string, const int32 &length, cons
nonspace.y = int32(d->edelta.nonspace * rotation.Sine() * 64); nonspace.y = int32(d->edelta.nonspace * rotation.Sine() * 64);
// set the pen position in 26.6 cartesian space coordinates // set the pen position in 26.6 cartesian space coordinates
FT_Vector pen;
pen.x = (int32)point.x * 64; pen.x = (int32)point.x * 64;
pen.y = (int32)point.y * 64; pen.y = (int32)point.y * 64;
slot=face->glyph; int32 strlength = strlen(string);
strlength=strlen(string);
if(length < strlength) if(length < strlength)
strlength = length; strlength = length;
for(i=0;i<strlength;i++) FT_Vector delta;
{ FT_GlyphSlot slot = face->glyph;
FT_UInt glyph_index = 0, previous = 0;
for (int32 i = 0; i < strlength; i++) {
FT_Set_Transform(face, &smatrix, &pen); FT_Set_Transform(face, &smatrix, &pen);
// Handle escapement padding option // Handle escapement padding option
if((uint8)string[i]<=0x20) if((uint8)string[i] <= 0x20) {
{
pen.x += space.x; pen.x += space.x;
pen.y += space.y; pen.y += space.y;
} } else {
else
{
pen.x += nonspace.x; pen.x += nonspace.x;
pen.y += nonspace.y; pen.y += nonspace.y;
} }
// get kerning and move pen // get kerning and move pen
if(use_kerning && previous && glyph_index) if(use_kerning && previous && glyph_index) {
{
FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta); FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta);
pen.x += delta.x; pen.x += delta.x;
pen.y += delta.y; pen.y += delta.y;
} }
error=FT_Load_Char(face,string[i], error = FT_Load_Char(face, string[i], (antialias ? FT_LOAD_RENDER : FT_LOAD_RENDER | FT_LOAD_MONOCHROME));
((antialias)?FT_LOAD_RENDER:FT_LOAD_RENDER | FT_LOAD_MONOCHROME) ); if (error)
continue;
if(!error)
{
if (antialias) if (antialias)
BlitGray2RGB32(&slot->bitmap, BlitGray2RGB32(&slot->bitmap, BPoint(slot->bitmap_left, point.y - (slot->bitmap_top - point.y)), d);
BPoint(slot->bitmap_left,point.y-(slot->bitmap_top-point.y)), d);
else else
BlitMono2RGB32(&slot->bitmap, BlitMono2RGB32(&slot->bitmap, BPoint(slot->bitmap_left, point.y - (slot->bitmap_top - point.y)), d);
BPoint(slot->bitmap_left,point.y-(slot->bitmap_top-point.y)), d);
}
// increment pen position // increment pen position
pen.x += slot->advance.x; pen.x += slot->advance.x;
@@ -2092,10 +2076,7 @@ void DisplayDriverImpl::DrawString(const char *string, const int32 &length, cons
d->penlocation.x = pen.x / 64; d->penlocation.x = pen.x / 64;
d->penlocation.y = pen.y / 64; d->penlocation.y = pen.y / 64;
FT_Done_Face(face);
Unlock(); Unlock();
} }
/*! /*!
@@ -2111,66 +2092,53 @@ float DisplayDriverImpl::StringWidth(const char *string, int32 length, const Dra
{ {
if(!string || !d) if(!string || !d)
return 0.0; return 0.0;
Lock(); Lock();
const ServerFont *font = &(d->font); const ServerFont *font = &(d->font);
FT_Face face; FT_Face face = font->GetFTFace();
FT_GlyphSlot slot; if(!face) {
FT_UInt glyph_index=0, previous=0;
FT_Vector pen,delta;
int16 error=0;
int32 strlength,i;
float returnval;
error=FT_New_Face(ftlib, font->GetPath(), 0, &face);
if(error)
{
Unlock(); Unlock();
return 0.0; return 0.0;
} }
slot=face->glyph; uint16 error = FT_Set_Char_Size(face, 0, int32(font->Size()) * 64, 72, 72);
if (error) {
bool use_kerning=FT_HAS_KERNING(face) && font->Spacing()==B_STRING_SPACING;
error=FT_Set_Char_Size(face, 0,int32(font->Size())*64,72,72);
if(error)
{
Unlock(); Unlock();
return 0.0; return 0.0;
} }
bool use_kerning = font->HasKerning() && font->Spacing() == B_STRING_SPACING;
// set the pen position in 26.6 cartesian space coordinates // set the pen position in 26.6 cartesian space coordinates
FT_Vector pen, delta;
pen.x = 0; pen.x = 0;
slot=face->glyph; int32 strlength = strlen(string);
strlength=strlen(string);
if (length < strlength) if (length < strlength)
strlength = length; strlength = length;
for(i=0;i<strlength;i++) FT_GlyphSlot slot = face->glyph;
{ FT_UInt glyph_index = 0, previous = 0;
for (int32 i = 0; i < strlength; i++) {
// get kerning and move pen // get kerning and move pen
if(use_kerning && previous && glyph_index) if (use_kerning && previous && glyph_index) {
{
FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta); FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta);
pen.x += delta.x; pen.x += delta.x;
} }
error = FT_Load_Char(face, string[i], FT_LOAD_MONOCHROME); error = FT_Load_Char(face, string[i], FT_LOAD_MONOCHROME);
if (error)
continue;
// increment pen position // increment pen position
pen.x += slot->advance.x; pen.x += slot->advance.x;
previous = glyph_index; previous = glyph_index;
} }
FT_Done_Face(face);
Unlock(); Unlock();
return pen.x >> 6;
returnval=pen.x>>6;
return returnval;
} }
/*! /*!
@@ -2189,52 +2157,38 @@ float DisplayDriverImpl::StringHeight(const char *string, int32 length, const Dr
{ {
if (!string || !d) if (!string || !d)
return 0.0; return 0.0;
Lock(); Lock();
const ServerFont *font = &(d->font); const ServerFont *font = &(d->font);
FT_Face face; FT_Face face = font->GetFTFace();
FT_GlyphSlot slot; if (!face) {
int16 error=0;
int32 strlength,i;
float returnval=0.0,ascent=0.0,descent=0.0;
error=FT_New_Face(ftlib, font->GetPath(), 0, &face);
if(error)
{
Unlock(); Unlock();
return 0.0; return 0.0;
} }
slot=face->glyph; uint16 error = FT_Set_Char_Size(face, 0, int32(font->Size()) * 64, 72, 72);
error=FT_Set_Char_Size(face, 0,int32(font->Size())*64,72,72); int32 strlength = strlen(string);
if(error)
{
Unlock();
return 0.0;
}
slot=face->glyph;
strlength=strlen(string);
if (length < strlength) if (length < strlength)
strlength = length; strlength = length;
for(i=0;i<strlength;i++) FT_GlyphSlot slot = face->glyph;
{ float ascent = 0.0, descent = 0.0;
FT_Load_Char(face,string[i],FT_LOAD_RENDER); for (int32 i = 0; i < strlength; i++) {
error = FT_Load_Char(face, string[i], FT_LOAD_MONOCHROME);
if (error)
continue;
if (slot->metrics.horiBearingY < slot->metrics.height) if (slot->metrics.horiBearingY < slot->metrics.height)
descent = MAX((slot->metrics.height - slot->metrics.horiBearingY) >> 6, descent); descent = MAX((slot->metrics.height - slot->metrics.horiBearingY) >> 6, descent);
else else
ascent = MAX(slot->bitmap.rows, ascent); ascent = MAX(slot->bitmap.rows, ascent);
} }
FT_Done_Face(face);
Unlock(); Unlock();
returnval=ascent+descent; return ascent + descent;
return returnval;
} }
/*! /*!