When I added my BuyNow screen saver to the image and ran it, the app_server
crashed. Turns out a call I use, BFont.GetBoundingBoxesForStrings was not implemented, and worse, there was bug in how the ServerApp read the parameters from the link. This was easy to fix to stop app_server from crashing, but it took me a while to figure out how to implement GetBoundingBoxesForStrings. Anyhow I implemented an initial version which works fairly well for now. I don't think the width is quite right, but it seems to match StringWidth(), so I guess it is good enough for now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21652 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1401,8 +1401,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
int32 lengthArray[numStrings];
|
int32 lengthArray[numStrings];
|
||||||
char *stringArray[numStrings];
|
char *stringArray[numStrings];
|
||||||
for (int32 i = 0; i < numStrings; i++) {
|
for (int32 i = 0; i < numStrings; i++) {
|
||||||
// TODO: who allocates the strings?!? If the link does it then we are leaking
|
// This version of ReadString allocates the strings, we free them below
|
||||||
// everywhere else!!
|
|
||||||
link.ReadString(&stringArray[i], (size_t *)&lengthArray[i]);
|
link.ReadString(&stringArray[i], (size_t *)&lengthArray[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1982,9 +1981,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
char *stringArray[numStrings];
|
char *stringArray[numStrings];
|
||||||
int32 lengthArray[numStrings];
|
int32 lengthArray[numStrings];
|
||||||
for(int32 i=0; i<numStrings; i++) {
|
for(int32 i=0; i<numStrings; i++) {
|
||||||
link.Read<int32>(&lengthArray[i]);
|
// This version of ReadString allocates the strings, we free them below
|
||||||
|
link.ReadString(&stringArray[i], (size_t *)&lengthArray[i]);
|
||||||
link.Read<escapement_delta>(&deltaArray[i]);
|
link.Read<escapement_delta>(&deltaArray[i]);
|
||||||
link.ReadString(&stringArray[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BRect rectArray[numStrings];
|
BRect rectArray[numStrings];
|
||||||
@@ -1999,7 +1998,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
font.SetSpacing(spacing);
|
font.SetSpacing(spacing);
|
||||||
font.SetFlags(flags);
|
font.SetFlags(flags);
|
||||||
|
|
||||||
// TODO implement for real
|
|
||||||
if (font.GetBoundingBoxesForStrings(stringArray, lengthArray,
|
if (font.GetBoundingBoxesForStrings(stringArray, lengthArray,
|
||||||
numStrings, rectArray, mode, deltaArray) == B_OK) {
|
numStrings, rectArray, mode, deltaArray) == B_OK) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <UTF8.h>
|
#include <UTF8.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// functions needed to convert a freetype vector graphics to a BShape
|
// functions needed to convert a freetype vector graphics to a BShape
|
||||||
inline BPoint
|
inline BPoint
|
||||||
@@ -496,6 +498,7 @@ ServerFont::GetBoundingBoxesAsString(const char charArray[], int32 numChars,
|
|||||||
BRect rectArray[], bool stringEscapement, font_metric_mode mode,
|
BRect rectArray[], bool stringEscapement, font_metric_mode mode,
|
||||||
escapement_delta delta)
|
escapement_delta delta)
|
||||||
{
|
{
|
||||||
|
// TODO: The mode is never used
|
||||||
if (!charArray || numChars <= 0 || !rectArray)
|
if (!charArray || numChars <= 0 || !rectArray)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
@@ -519,12 +522,12 @@ ServerFont::GetBoundingBoxesAsString(const char charArray[], int32 numChars,
|
|||||||
+ face->glyph->metrics.horiAdvance / 64.0;
|
+ face->glyph->metrics.horiAdvance / 64.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rectArray[i].left += float(face->glyph->metrics.horiBearingX) /64.0;
|
rectArray[i].left += float(face->glyph->metrics.horiBearingX) / 64.0;
|
||||||
rectArray[i].right += float(face->glyph->metrics.horiBearingX
|
rectArray[i].right += float(face->glyph->metrics.horiBearingX
|
||||||
+ face->glyph->metrics.width) / 64.0;
|
+ face->glyph->metrics.width) / 64.0;
|
||||||
rectArray[i].top = -float(face->glyph->metrics.horiBearingY) / 64.0;
|
rectArray[i].top = -float(face->glyph->metrics.horiBearingY) / 64.0;
|
||||||
rectArray[i].bottom = float(face->glyph->metrics.height
|
rectArray[i].bottom = float(face->glyph->metrics.height
|
||||||
- face->glyph->metrics.horiBearingY) /64.0;
|
- face->glyph->metrics.horiBearingY) / 64.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PutTransformedFace(face);
|
PutTransformedFace(face);
|
||||||
@@ -536,6 +539,7 @@ status_t
|
|||||||
ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[],
|
ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[],
|
||||||
int32 numStrings, BRect rectArray[], font_metric_mode mode, escapement_delta deltaArray[])
|
int32 numStrings, BRect rectArray[], font_metric_mode mode, escapement_delta deltaArray[])
|
||||||
{
|
{
|
||||||
|
// TODO: The mode is never used
|
||||||
if (!charArray || !lengthArray|| numStrings <= 0 || !rectArray || !deltaArray)
|
if (!charArray || !lengthArray|| numStrings <= 0 || !rectArray || !deltaArray)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
@@ -544,7 +548,28 @@ ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[],
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
for (int32 i = 0; i < numStrings; i++) {
|
for (int32 i = 0; i < numStrings; i++) {
|
||||||
// TODO: ...
|
int32 numChars = lengthArray[i];
|
||||||
|
const char *string = charArray[i];
|
||||||
|
escapement_delta delta = deltaArray[i];
|
||||||
|
|
||||||
|
rectArray[i].left = 0.0;
|
||||||
|
for (int32 j = 0; j < numChars; j++) {
|
||||||
|
uint32 charCode = UTF8ToCharCode(&string);
|
||||||
|
FT_Load_Char(face, charCode, FT_LOAD_NO_BITMAP);
|
||||||
|
|
||||||
|
// TODO: In my testing the width doesn't seem quite right (a
|
||||||
|
// little too long), though I need to do more comparisions with BeOS
|
||||||
|
rectArray[i].right += (face->glyph->advance.x >> 6);
|
||||||
|
rectArray[i].right += is_white_space(charCode) ? delta.space : delta.nonspace;
|
||||||
|
|
||||||
|
float top = -(face->glyph->metrics.horiBearingY >> 6);
|
||||||
|
if (top < rectArray[i].top)
|
||||||
|
rectArray[i].top = top;
|
||||||
|
float bottom = (face->glyph->metrics.height
|
||||||
|
- face->glyph->metrics.horiBearingY) >> 6;
|
||||||
|
if (bottom > rectArray[i].bottom)
|
||||||
|
rectArray[i].bottom = bottom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PutTransformedFace(face);
|
PutTransformedFace(face);
|
||||||
|
|||||||
Reference in New Issue
Block a user