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