app_server: Add char limit to GlyphLayoutEngine::LayoutGlyphs().
Many of the consumers fill in data into preallocated arrays. Some of them already ignored values past the array size manually, some didn't. Add a maxChar argument and set it from the incoming array sizes for the various consumer cases.
This commit is contained in:
parent
64a11edb02
commit
8071db3259
@ -2204,7 +2204,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
ServerFont font;
|
||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
||||
if (status == B_OK) {
|
||||
status = font.GetHasGlyphs(charArray, numBytes, hasArray);
|
||||
status = font.GetHasGlyphs(charArray, numBytes, numChars,
|
||||
hasArray);
|
||||
if (status == B_OK) {
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach(hasArray, numChars * sizeof(bool));
|
||||
@ -2251,7 +2252,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
ServerFont font;
|
||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
||||
if (status == B_OK) {
|
||||
status = font.GetEdges(charArray, numBytes, edgeArray);
|
||||
status = font.GetEdges(charArray, numBytes, numChars,
|
||||
edgeArray);
|
||||
if (status == B_OK) {
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach(edgeArray, numChars * sizeof(edge_info));
|
||||
@ -2503,7 +2505,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
// TODO: implement for real
|
||||
if (font.GetBoundingBoxes(charArray, numBytes,
|
||||
rectArray, stringEscapement, mode, delta,
|
||||
numChars, rectArray, stringEscapement, mode, delta,
|
||||
code == AS_GET_BOUNDINGBOXES_STRING) == B_OK) {
|
||||
|
||||
fLink.StartMessage(B_OK);
|
||||
|
@ -696,16 +696,17 @@ class HasGlyphsConsumer {
|
||||
|
||||
|
||||
status_t
|
||||
ServerFont::GetHasGlyphs(const char* string, int32 numBytes,
|
||||
ServerFont::GetHasGlyphs(const char* string, int32 numBytes, int32 numChars,
|
||||
bool* hasArray) const
|
||||
{
|
||||
if (!string || numBytes <= 0 || !hasArray)
|
||||
if (string == NULL || numBytes <= 0 || numChars <= 0 || hasArray == NULL)
|
||||
return B_BAD_DATA;
|
||||
|
||||
HasGlyphsConsumer consumer(hasArray);
|
||||
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||
NULL, fSpacing))
|
||||
numChars, NULL, fSpacing)) {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
@ -745,15 +746,15 @@ class EdgesConsumer {
|
||||
|
||||
|
||||
status_t
|
||||
ServerFont::GetEdges(const char* string, int32 numBytes,
|
||||
ServerFont::GetEdges(const char* string, int32 numBytes, int32 numChars,
|
||||
edge_info* edges) const
|
||||
{
|
||||
if (!string || numBytes <= 0 || !edges)
|
||||
if (string == NULL || numBytes <= 0 || numChars <= 0 || edges == NULL)
|
||||
return B_BAD_DATA;
|
||||
|
||||
EdgesConsumer consumer(edges, fSize);
|
||||
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||
NULL, fSpacing)) {
|
||||
numChars, NULL, fSpacing)) {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -780,12 +781,10 @@ ServerFont::GetEdges(const char* string, int32 numBytes,
|
||||
|
||||
class BPointEscapementConsumer {
|
||||
public:
|
||||
BPointEscapementConsumer(BPoint* escapements, BPoint* offsets,
|
||||
int32 numChars, float size)
|
||||
BPointEscapementConsumer(BPoint* escapements, BPoint* offsets, float size)
|
||||
:
|
||||
fEscapements(escapements),
|
||||
fOffsets(offsets),
|
||||
fNumChars(numChars),
|
||||
fSize(size)
|
||||
{
|
||||
}
|
||||
@ -808,9 +807,6 @@ public:
|
||||
private:
|
||||
inline bool _Set(int32 index, double x, double y)
|
||||
{
|
||||
if (index >= fNumChars)
|
||||
return false;
|
||||
|
||||
fEscapements[index].x = x / fSize;
|
||||
fEscapements[index].y = y / fSize;
|
||||
if (fOffsets) {
|
||||
@ -827,7 +823,6 @@ private:
|
||||
|
||||
BPoint* fEscapements;
|
||||
BPoint* fOffsets;
|
||||
int32 fNumChars;
|
||||
float fSize;
|
||||
};
|
||||
|
||||
@ -840,10 +835,9 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, int32 numChars,
|
||||
if (!string || numBytes <= 0 || !escapementArray)
|
||||
return B_BAD_DATA;
|
||||
|
||||
BPointEscapementConsumer consumer(escapementArray, offsetArray, numChars,
|
||||
fSize);
|
||||
BPointEscapementConsumer consumer(escapementArray, offsetArray, fSize);
|
||||
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||
&delta, fSpacing)) {
|
||||
numChars, &delta, fSpacing)) {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -853,10 +847,9 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, int32 numChars,
|
||||
|
||||
class WidthEscapementConsumer {
|
||||
public:
|
||||
WidthEscapementConsumer(float* widths, int32 numChars, float size)
|
||||
WidthEscapementConsumer(float* widths, float size)
|
||||
:
|
||||
fWidths(widths),
|
||||
fNumChars(numChars),
|
||||
fSize(size)
|
||||
{
|
||||
}
|
||||
@ -873,16 +866,12 @@ public:
|
||||
FontCacheEntry* entry, double x, double y, double advanceX,
|
||||
double advanceY)
|
||||
{
|
||||
if (index >= fNumChars)
|
||||
return false;
|
||||
|
||||
fWidths[index] = advanceX / fSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
float* fWidths;
|
||||
int32 fNumChars;
|
||||
float fSize;
|
||||
};
|
||||
|
||||
@ -895,9 +884,9 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, int32 numChars,
|
||||
if (!string || numBytes <= 0 || !widthArray)
|
||||
return B_BAD_DATA;
|
||||
|
||||
WidthEscapementConsumer consumer(widthArray, numChars, fSize);
|
||||
WidthEscapementConsumer consumer(widthArray, fSize);
|
||||
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||
&delta, fSpacing)) {
|
||||
numChars, &delta, fSpacing)) {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -997,19 +986,19 @@ class BoundingBoxConsumer {
|
||||
|
||||
|
||||
status_t
|
||||
ServerFont::GetBoundingBoxes(const char* string, int32 numBytes,
|
||||
ServerFont::GetBoundingBoxes(const char* string, int32 numBytes, int32 numChars,
|
||||
BRect rectArray[], bool stringEscapement, font_metric_mode mode,
|
||||
escapement_delta delta, bool asString)
|
||||
{
|
||||
// TODO: The font_metric_mode is not used
|
||||
if (!string || numBytes <= 0 || !rectArray)
|
||||
if (string == NULL || numBytes <= 0 || numChars <= 0 || rectArray == NULL)
|
||||
return B_BAD_DATA;
|
||||
|
||||
Transformable transform(EmbeddedTransformation());
|
||||
|
||||
BoundingBoxConsumer consumer(transform, rectArray, asString);
|
||||
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||
stringEscapement ? &delta : NULL, fSpacing)) {
|
||||
numChars, stringEscapement ? &delta : NULL, fSpacing)) {
|
||||
return B_OK;
|
||||
}
|
||||
return B_ERROR;
|
||||
@ -1034,7 +1023,7 @@ ServerFont::GetBoundingBoxesForStrings(char *charArray[], size_t lengthArray[],
|
||||
|
||||
BoundingBoxConsumer consumer(transform, NULL, true);
|
||||
if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||
&delta, fSpacing)) {
|
||||
INT32_MAX, &delta, fSpacing)) {
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@ -1077,7 +1066,7 @@ ServerFont::StringWidth(const char *string, int32 numBytes,
|
||||
|
||||
StringWidthConsumer consumer;
|
||||
if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
|
||||
deltaArray, fSpacing)) {
|
||||
INT32_MAX, deltaArray, fSpacing)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
@ -116,10 +116,12 @@ class ServerFont {
|
||||
int32 numChars, BShape *shapeArray[]) const;
|
||||
|
||||
status_t GetHasGlyphs(const char charArray[],
|
||||
int32 numBytes, bool hasArray[]) const;
|
||||
int32 numBytes, int32 numChars,
|
||||
bool hasArray[]) const;
|
||||
|
||||
status_t GetEdges(const char charArray[], int32 numBytes,
|
||||
edge_info edgeArray[]) const;
|
||||
int32 numChars, edge_info edgeArray[])
|
||||
const;
|
||||
|
||||
status_t GetEscapements(const char charArray[],
|
||||
int32 numBytes, int32 numChars,
|
||||
@ -133,8 +135,8 @@ class ServerFont {
|
||||
float widthArray[]) const;
|
||||
|
||||
status_t GetBoundingBoxes(const char charArray[],
|
||||
int32 numBytes, BRect rectArray[],
|
||||
bool stringEscapement,
|
||||
int32 numBytes, int32 numChars,
|
||||
BRect rectArray[], bool stringEscapement,
|
||||
font_metric_mode mode,
|
||||
escapement_delta delta,
|
||||
bool asString);
|
||||
|
@ -363,8 +363,8 @@ AGGTextRenderer::RenderString(const char* string, uint32 length,
|
||||
transformedOutline, transformedContourOutline,
|
||||
transform, transformOffset, nextCharPos, *this);
|
||||
|
||||
GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, delta,
|
||||
fFont.Spacing(), NULL, cacheReference);
|
||||
GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, INT32_MAX,
|
||||
delta, fFont.Spacing(), NULL, cacheReference);
|
||||
|
||||
return transform.TransformBounds(renderer.Bounds());
|
||||
}
|
||||
@ -400,8 +400,8 @@ AGGTextRenderer::RenderString(const char* string, uint32 length,
|
||||
transformedOutline, transformedContourOutline,
|
||||
transform, transformOffset, nextCharPos, *this);
|
||||
|
||||
GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, NULL,
|
||||
fFont.Spacing(), offsets, cacheReference);
|
||||
GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, INT32_MAX,
|
||||
NULL, fFont.Spacing(), offsets, cacheReference);
|
||||
|
||||
return transform.TransformBounds(renderer.Bounds());
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public:
|
||||
static bool LayoutGlyphs(GlyphConsumer& consumer,
|
||||
const ServerFont& font,
|
||||
const char* utf8String,
|
||||
int32 length,
|
||||
int32 length, int32 maxChars,
|
||||
const escapement_delta* delta = NULL,
|
||||
uint8 spacing = B_BITMAP_SPACING,
|
||||
const BPoint* offsets = NULL,
|
||||
@ -171,7 +171,7 @@ template<class GlyphConsumer>
|
||||
inline bool
|
||||
GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer,
|
||||
const ServerFont& font,
|
||||
const char* utf8String, int32 length,
|
||||
const char* utf8String, int32 length, int32 maxChars,
|
||||
const escapement_delta* delta, uint8 spacing,
|
||||
const BPoint* offsets, FontCacheReference* _cacheReference)
|
||||
{
|
||||
@ -217,7 +217,7 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer,
|
||||
int32 index = 0;
|
||||
bool writeLocked = false;
|
||||
const char* start = utf8String;
|
||||
while ((charCode = UTF8ToCharCode(&utf8String))) {
|
||||
while (maxChars-- > 0 && (charCode = UTF8ToCharCode(&utf8String)) != 0) {
|
||||
|
||||
if (offsets != NULL) {
|
||||
// Use direct glyph locations instead of calculating them
|
||||
|
Loading…
Reference in New Issue
Block a user