app_server: Port ServerPicture to the new PicturePlayer API.

This allows for bounds checks on strings and bitmap data to avoid
crashing due to corrupted user data. It also avoids copying the data
where possible.
This commit is contained in:
Michael Lotz
2015-09-05 16:09:32 +02:00
parent eec73693e0
commit 4176076be1
+194 -265
View File
@@ -218,7 +218,7 @@ ShapePainter::Draw(BRect frame, bool filled)
static void static void
get_polygon_frame(const BPoint* points, int32 numPoints, BRect* _frame) get_polygon_frame(const BPoint* points, uint32 numPoints, BRect* _frame)
{ {
ASSERT(numPoints > 0); ASSERT(numPoints > 0);
@@ -247,29 +247,26 @@ get_polygon_frame(const BPoint* points, int32 numPoints, BRect* _frame)
static void static void
nop() move_pen_by(void* _context, const BPoint& delta)
{
}
static void
move_pen_by(DrawingContext* context, BPoint delta)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->CurrentState()->SetPenLocation( context->CurrentState()->SetPenLocation(
context->CurrentState()->PenLocation() + delta); context->CurrentState()->PenLocation() + delta);
} }
static void static void
stroke_line(DrawingContext* context, BPoint start, BPoint end) stroke_line(void* _context, const BPoint& _start, const BPoint& _end)
{ {
BPoint penPos = end; DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
BPoint start = _start;
BPoint end = _end;
context->ConvertToScreenForDrawing(&start); context->ConvertToScreenForDrawing(&start);
context->ConvertToScreenForDrawing(&end); context->ConvertToScreenForDrawing(&end);
context->GetDrawingEngine()->StrokeLine(start, end); context->GetDrawingEngine()->StrokeLine(start, end);
context->CurrentState()->SetPenLocation(penPos); context->CurrentState()->SetPenLocation(_end);
// the DrawingEngine/Painter does not need to be updated, since this // the DrawingEngine/Painter does not need to be updated, since this
// effects only the view->screen coord conversion, which is handled // effects only the view->screen coord conversion, which is handled
// by the view only // by the view only
@@ -277,24 +274,26 @@ stroke_line(DrawingContext* context, BPoint start, BPoint end)
static void static void
stroke_rect(DrawingContext* context, BRect rect) draw_rect(void* _context, const BRect& _rect, bool fill)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
BRect rect = _rect;
context->ConvertToScreenForDrawing(&rect); context->ConvertToScreenForDrawing(&rect);
context->GetDrawingEngine()->StrokeRect(rect); if (fill)
context->GetDrawingEngine()->FillRect(rect);
else
context->GetDrawingEngine()->StrokeRect(rect);
} }
static void static void
fill_rect(DrawingContext* context, BRect rect) draw_round_rect(void* _context, const BRect& _rect, const BPoint& radii,
bool fill)
{ {
context->ConvertToScreenForDrawing(&rect); DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->GetDrawingEngine()->FillRect(rect); BRect rect = _rect;
}
static void
draw_round_rect(DrawingContext* context, BRect rect, BPoint radii, bool fill)
{
context->ConvertToScreenForDrawing(&rect); context->ConvertToScreenForDrawing(&rect);
float scale = context->CurrentState()->CombinedScale(); float scale = context->CurrentState()->CombinedScale();
context->GetDrawingEngine()->DrawRoundRect(rect, radii.x * scale, context->GetDrawingEngine()->DrawRoundRect(rect, radii.x * scale,
@@ -303,183 +302,94 @@ draw_round_rect(DrawingContext* context, BRect rect, BPoint radii, bool fill)
static void static void
stroke_round_rect(DrawingContext* context, BRect rect, BPoint radii) draw_bezier(void* _context, size_t numPoints, const BPoint viewPoints[],
bool fill)
{ {
draw_round_rect(context, rect, radii, false); DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
}
const size_t kSupportedPoints = 4;
static void if (numPoints != kSupportedPoints)
fill_round_rect(DrawingContext* context, BRect rect, BPoint radii)
{
draw_round_rect(context, rect, radii, true);
}
static void
stroke_bezier(DrawingContext* context, const BPoint* viewPoints)
{
BPoint points[4];
context->ConvertToScreenForDrawing(points, viewPoints, 4);
context->GetDrawingEngine()->DrawBezier(points, false);
}
static void
fill_bezier(DrawingContext* context, const BPoint* viewPoints)
{
BPoint points[4];
context->ConvertToScreenForDrawing(points, viewPoints, 4);
context->GetDrawingEngine()->DrawBezier(points, true);
}
static void
stroke_arc(DrawingContext* context, BPoint center, BPoint radii,
float startTheta, float arcTheta)
{
BRect rect(center.x - radii.x, center.y - radii.y,
center.x + radii.x - 1, center.y + radii.y - 1);
context->ConvertToScreenForDrawing(&rect);
context->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, false);
}
static void
fill_arc(DrawingContext* context, BPoint center, BPoint radii,
float startTheta, float arcTheta)
{
BRect rect(center.x - radii.x, center.y - radii.y,
center.x + radii.x - 1, center.y + radii.y - 1);
context->ConvertToScreenForDrawing(&rect);
context->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, true);
}
static void
stroke_ellipse(DrawingContext* context, BPoint center, BPoint radii)
{
BRect rect(center.x - radii.x, center.y - radii.y,
center.x + radii.x - 1, center.y + radii.y - 1);
context->ConvertToScreenForDrawing(&rect);
context->GetDrawingEngine()->DrawEllipse(rect, false);
}
static void
fill_ellipse(DrawingContext* context, BPoint center, BPoint radii)
{
BRect rect(center.x - radii.x, center.y - radii.y,
center.x + radii.x - 1, center.y + radii.y - 1);
context->ConvertToScreenForDrawing(&rect);
context->GetDrawingEngine()->DrawEllipse(rect, true);
}
static void
stroke_polygon(DrawingContext* context, int32 numPoints,
const BPoint* viewPoints, bool isClosed)
{
if (numPoints <= 0)
return; return;
if (numPoints <= 200) { BPoint points[kSupportedPoints];
// fast path: no malloc/free, also avoid context->ConvertToScreenForDrawing(points, viewPoints, kSupportedPoints);
// constructor/destructor calls
char data[200 * sizeof(BPoint)];
BPoint* points = (BPoint*)data;
context->ConvertToScreenForDrawing(points, viewPoints, numPoints); context->GetDrawingEngine()->DrawBezier(points, fill);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
context->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
false, isClosed && numPoints > 2);
} else {
// avoid constructor/destructor calls by
// using malloc instead of new []
BPoint* points = (BPoint*)malloc(numPoints * sizeof(BPoint));
if (points == NULL)
return;
context->ConvertToScreenForDrawing(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
context->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
false, isClosed && numPoints > 2);
free(points);
}
} }
static void static void
fill_polygon(DrawingContext* context, int32 numPoints, draw_arc(void* _context, const BPoint& center, const BPoint& radii,
const BPoint* viewPoints) float startTheta, float arcTheta, bool fill)
{ {
if (numPoints <= 0) DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
BRect rect(center.x - radii.x, center.y - radii.y,
center.x + radii.x - 1, center.y + radii.y - 1);
context->ConvertToScreenForDrawing(&rect);
context->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, fill);
}
static void
draw_ellipse(void* _context, const BRect& _rect, bool fill)
{
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
BRect rect = _rect;
context->ConvertToScreenForDrawing(&rect);
context->GetDrawingEngine()->DrawEllipse(rect, fill);
}
static void
draw_polygon(void* _context, size_t numPoints, const BPoint viewPoints[],
bool isClosed, bool fill)
{
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
if (numPoints == 0)
return; return;
if (numPoints <= 200) { const size_t kMaxStackCount = 200;
// fast path: no malloc/free, also avoid char stackData[kMaxStackCount * sizeof(BPoint)];
// constructor/destructor calls BPoint* points = (BPoint*)stackData;
char data[200 * sizeof(BPoint)]; if (numPoints > kMaxStackCount) {
BPoint* points = (BPoint*)data; points = (BPoint*)malloc(numPoints * sizeof(BPoint));
context->ConvertToScreenForDrawing(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
context->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
true, true);
} else {
// avoid constructor/destructor calls by
// using malloc instead of new []
BPoint* points = (BPoint*)malloc(numPoints * sizeof(BPoint));
if (points == NULL) if (points == NULL)
return; return;
context->ConvertToScreenForDrawing(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
context->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
true, true);
free(points);
} }
context->ConvertToScreenForDrawing(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
context->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
fill, isClosed && numPoints > 2);
if (numPoints > kMaxStackCount)
free(points);
} }
static void static void
stroke_shape(DrawingContext* context, const BShape* shape) draw_shape(void* _context, const BShape& shape, bool fill)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
ShapePainter drawShape(context); ShapePainter drawShape(context);
drawShape.Iterate(shape); drawShape.Iterate(&shape);
drawShape.Draw(shape->Bounds(), false); drawShape.Draw(shape.Bounds(), fill);
} }
static void static void
fill_shape(DrawingContext* context, const BShape* shape) draw_string(void* _context, const char* string, size_t length, float deltaSpace,
{
ShapePainter drawShape(context);
drawShape.Iterate(shape);
drawShape.Draw(shape->Bounds(), true);
}
static void
draw_string(DrawingContext* context, const char* string, float deltaSpace,
float deltaNonSpace) float deltaNonSpace)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
// NOTE: the picture data was recorded with a "set pen location" // NOTE: the picture data was recorded with a "set pen location"
// command inserted before the "draw string" command, so we can // command inserted before the "draw string" command, so we can
// use PenLocation() // use PenLocation()
@@ -487,7 +397,7 @@ draw_string(DrawingContext* context, const char* string, float deltaSpace,
escapement_delta delta = { deltaSpace, deltaNonSpace }; escapement_delta delta = { deltaSpace, deltaNonSpace };
context->ConvertToScreenForDrawing(&location); context->ConvertToScreenForDrawing(&location);
location = context->GetDrawingEngine()->DrawString(string, strlen(string), location = context->GetDrawingEngine()->DrawString(string, length,
location, &delta); location, &delta);
context->ConvertFromScreenForDrawing(&location); context->ConvertFromScreenForDrawing(&location);
@@ -499,26 +409,31 @@ draw_string(DrawingContext* context, const char* string, float deltaSpace,
static void static void
draw_pixels(DrawingContext* context, BRect src, BRect dest, int32 width, draw_pixels(void* _context, const BRect& src, const BRect& _dest, uint32 width,
int32 height, int32 bytesPerRow, int32 pixelFormat, int32 options, uint32 height, size_t bytesPerRow, color_space pixelFormat, uint32 options,
const void* data) const void* data, size_t length)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
UtilityBitmap bitmap(BRect(0, 0, width - 1, height - 1), UtilityBitmap bitmap(BRect(0, 0, width - 1, height - 1),
(color_space)pixelFormat, 0, bytesPerRow); (color_space)pixelFormat, 0, bytesPerRow);
if (!bitmap.IsValid()) if (!bitmap.IsValid())
return; return;
memcpy(bitmap.Bits(), data, height * bytesPerRow); memcpy(bitmap.Bits(), data, std::min(height * bytesPerRow, length));
BRect dest = _dest;
context->ConvertToScreenForDrawing(&dest); context->ConvertToScreenForDrawing(&dest);
context->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest, options); context->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest, options);
} }
static void static void
draw_picture(DrawingContext* context, BPoint where, int32 token) draw_picture(void* _context, const BPoint& where, int32 token)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
ServerPicture* picture = context->GetPicture(token); ServerPicture* picture = context->GetPicture(token);
if (picture != NULL) { if (picture != NULL) {
context->PushState(); context->PushState();
@@ -535,21 +450,23 @@ draw_picture(DrawingContext* context, BPoint where, int32 token)
static void static void
set_clipping_rects(DrawingContext* context, const BRect* rects, set_clipping_rects(void* _context, size_t numRects, const BRect rects[])
uint32 numRects)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
// TODO: This might be too slow, we should copy the rects // TODO: This might be too slow, we should copy the rects
// directly to BRegion's internal data // directly to BRegion's internal data
BRegion region; BRegion region;
for (uint32 c = 0; c < numRects; c++) for (uint32 c = 0; c < numRects; c++)
region.Include(rects[c]); region.Include(rects[c]);
context->SetUserClipping(&region); context->SetUserClipping(&region);
context->UpdateCurrentDrawingRegion(); context->UpdateCurrentDrawingRegion();
} }
static void static void
clip_to_picture(DrawingContext* context, BPicture* picture, BPoint pt, clip_to_picture(void* context, const BPicture& picture, const BPoint& pt,
bool clipToInverse) bool clipToInverse)
{ {
printf("ClipToPicture(picture, BPoint(%.2f, %.2f), %s)\n", printf("ClipToPicture(picture, BPoint(%.2f, %.2f), %s)\n",
@@ -558,15 +475,17 @@ clip_to_picture(DrawingContext* context, BPicture* picture, BPoint pt,
static void static void
push_state(DrawingContext* context) push_state(void* _context)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->PushState(); context->PushState();
} }
static void static void
pop_state(DrawingContext* context) pop_state(void* _context)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->PopState(); context->PopState();
BPoint p(0, 0); BPoint p(0, 0);
@@ -579,41 +498,45 @@ pop_state(DrawingContext* context)
// TODO: Be smart and actually take advantage of these methods: // TODO: Be smart and actually take advantage of these methods:
// only apply state changes when they are called // only apply state changes when they are called
static void static void
enter_state_change(DrawingContext* context) enter_state_change(void* context)
{ {
} }
static void static void
exit_state_change(DrawingContext* context) exit_state_change(void* _context)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->ResyncDrawState(); context->ResyncDrawState();
} }
static void static void
enter_font_state(DrawingContext* context) enter_font_state(void* context)
{ {
} }
static void static void
exit_font_state(DrawingContext* context) exit_font_state(void* _context)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->GetDrawingEngine()->SetFont(context->CurrentState()->Font()); context->GetDrawingEngine()->SetFont(context->CurrentState()->Font());
} }
static void static void
set_origin(DrawingContext* context, BPoint pt) set_origin(void* _context, const BPoint& pt)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->CurrentState()->SetOrigin(pt); context->CurrentState()->SetOrigin(pt);
} }
static void static void
set_pen_location(DrawingContext* context, BPoint pt) set_pen_location(void* _context, const BPoint& pt)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->CurrentState()->SetPenLocation(pt); context->CurrentState()->SetPenLocation(pt);
// the DrawingEngine/Painter does not need to be updated, since this // the DrawingEngine/Painter does not need to be updated, since this
// effects only the view->screen coord conversion, which is handled // effects only the view->screen coord conversion, which is handled
@@ -622,17 +545,19 @@ set_pen_location(DrawingContext* context, BPoint pt)
static void static void
set_drawing_mode(DrawingContext* context, drawing_mode mode) set_drawing_mode(void* _context, drawing_mode mode)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->CurrentState()->SetDrawingMode(mode); context->CurrentState()->SetDrawingMode(mode);
context->GetDrawingEngine()->SetDrawingMode(mode); context->GetDrawingEngine()->SetDrawingMode(mode);
} }
static void static void
set_line_mode(DrawingContext* context, cap_mode capMode, join_mode joinMode, set_line_mode(void* _context, cap_mode capMode, join_mode joinMode,
float miterLimit) float miterLimit)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
DrawState* state = context->CurrentState(); DrawState* state = context->CurrentState();
state->SetLineCapMode(capMode); state->SetLineCapMode(capMode);
state->SetLineJoinMode(joinMode); state->SetLineJoinMode(joinMode);
@@ -642,8 +567,9 @@ set_line_mode(DrawingContext* context, cap_mode capMode, join_mode joinMode,
static void static void
set_pen_size(DrawingContext* context, float size) set_pen_size(void* _context, float size)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->CurrentState()->SetPenSize(size); context->CurrentState()->SetPenSize(size);
context->GetDrawingEngine()->SetPenSize( context->GetDrawingEngine()->SetPenSize(
context->CurrentState()->PenSize()); context->CurrentState()->PenSize());
@@ -653,32 +579,36 @@ set_pen_size(DrawingContext* context, float size)
static void static void
set_fore_color(DrawingContext* context, rgb_color color) set_fore_color(void* _context, const rgb_color& color)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->CurrentState()->SetHighColor(color); context->CurrentState()->SetHighColor(color);
context->GetDrawingEngine()->SetHighColor(color); context->GetDrawingEngine()->SetHighColor(color);
} }
static void static void
set_back_color(DrawingContext* context, rgb_color color) set_back_color(void* _context, const rgb_color& color)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->CurrentState()->SetLowColor(color); context->CurrentState()->SetLowColor(color);
context->GetDrawingEngine()->SetLowColor(color); context->GetDrawingEngine()->SetLowColor(color);
} }
static void static void
set_stipple_pattern(DrawingContext* context, pattern p) set_stipple_pattern(void* _context, const pattern& pattern)
{ {
context->CurrentState()->SetPattern(Pattern(p)); DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->GetDrawingEngine()->SetPattern(p); context->CurrentState()->SetPattern(Pattern(pattern));
context->GetDrawingEngine()->SetPattern(pattern);
} }
static void static void
set_scale(DrawingContext* context, float scale) set_scale(void* _context, float scale)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
context->CurrentState()->SetScale(scale); context->CurrentState()->SetScale(scale);
context->ResyncDrawState(); context->ResyncDrawState();
@@ -688,8 +618,11 @@ set_scale(DrawingContext* context, float scale)
static void static void
set_font_family(DrawingContext* context, const char* family) set_font_family(void* _context, const char* _family, size_t length)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
BString family(_family, length);
FontStyle* fontStyle = gFontManager->GetStyleByIndex(family, 0); FontStyle* fontStyle = gFontManager->GetStyleByIndex(family, 0);
ServerFont font; ServerFont font;
font.SetStyle(fontStyle); font.SetStyle(fontStyle);
@@ -698,8 +631,11 @@ set_font_family(DrawingContext* context, const char* family)
static void static void
set_font_style(DrawingContext* context, const char* style) set_font_style(void* _context, const char* _style, size_t length)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
BString style(_style, length);
ServerFont font(context->CurrentState()->Font()); ServerFont font(context->CurrentState()->Font());
FontStyle* fontStyle = gFontManager->GetStyle(font.Family(), style); FontStyle* fontStyle = gFontManager->GetStyle(font.Family(), style);
@@ -710,8 +646,9 @@ set_font_style(DrawingContext* context, const char* style)
static void static void
set_font_spacing(DrawingContext* context, int32 spacing) set_font_spacing(void* _context, uint8 spacing)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
ServerFont font; ServerFont font;
font.SetSpacing(spacing); font.SetSpacing(spacing);
context->CurrentState()->SetFont(font, B_FONT_SPACING); context->CurrentState()->SetFont(font, B_FONT_SPACING);
@@ -719,8 +656,9 @@ set_font_spacing(DrawingContext* context, int32 spacing)
static void static void
set_font_size(DrawingContext* context, float size) set_font_size(void* _context, float size)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
ServerFont font; ServerFont font;
font.SetSize(size); font.SetSize(size);
context->CurrentState()->SetFont(font, B_FONT_SIZE); context->CurrentState()->SetFont(font, B_FONT_SIZE);
@@ -728,8 +666,9 @@ set_font_size(DrawingContext* context, float size)
static void static void
set_font_rotate(DrawingContext* context, float rotation) set_font_rotation(void* _context, float rotation)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
ServerFont font; ServerFont font;
font.SetRotation(rotation); font.SetRotation(rotation);
context->CurrentState()->SetFont(font, B_FONT_ROTATION); context->CurrentState()->SetFont(font, B_FONT_ROTATION);
@@ -737,8 +676,9 @@ set_font_rotate(DrawingContext* context, float rotation)
static void static void
set_font_encoding(DrawingContext* context, int32 encoding) set_font_encoding(void* _context, uint8 encoding)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
ServerFont font; ServerFont font;
font.SetEncoding(encoding); font.SetEncoding(encoding);
context->CurrentState()->SetFont(font, B_FONT_ENCODING); context->CurrentState()->SetFont(font, B_FONT_ENCODING);
@@ -746,8 +686,9 @@ set_font_encoding(DrawingContext* context, int32 encoding)
static void static void
set_font_flags(DrawingContext* context, int32 flags) set_font_flags(void* _context, uint32 flags)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
ServerFont font; ServerFont font;
font.SetFlags(flags); font.SetFlags(flags);
context->CurrentState()->SetFont(font, B_FONT_FLAGS); context->CurrentState()->SetFont(font, B_FONT_FLAGS);
@@ -755,8 +696,9 @@ set_font_flags(DrawingContext* context, int32 flags)
static void static void
set_font_shear(DrawingContext* context, float shear) set_font_shear(void* _context, float shear)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
ServerFont font; ServerFont font;
font.SetShear(shear); font.SetShear(shear);
context->CurrentState()->SetFont(font, B_FONT_SHEAR); context->CurrentState()->SetFont(font, B_FONT_SHEAR);
@@ -764,8 +706,9 @@ set_font_shear(DrawingContext* context, float shear)
static void static void
set_font_face(DrawingContext* context, int32 face) set_font_face(void* _context, uint16 face)
{ {
DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
ServerFont font; ServerFont font;
font.SetFace(face); font.SetFace(face);
context->CurrentState()->SetFont(font, B_FONT_FACE); context->CurrentState()->SetFont(font, B_FONT_FACE);
@@ -773,68 +716,54 @@ set_font_face(DrawingContext* context, int32 face)
static void static void
set_blending_mode(DrawingContext* context, int16 alphaSrcMode, int16 alphaFncMode) set_blending_mode(void* _context, source_alpha alphaSrcMode,
alpha_function alphaFncMode)
{ {
context->CurrentState()->SetBlendingMode((source_alpha)alphaSrcMode, DrawingContext* context = reinterpret_cast<DrawingContext *>(_context);
(alpha_function)alphaFncMode); context->CurrentState()->SetBlendingMode(alphaSrcMode, alphaFncMode);
} }
static void static const BPrivate::picture_player_callbacks kPicturePlayerCallbacks = {
reserved() move_pen_by,
{ stroke_line,
} draw_rect,
draw_round_rect,
draw_bezier,
const static void* kTableEntries[] = { draw_arc,
(const void*)nop, // 0 draw_ellipse,
(const void*)move_pen_by, draw_polygon,
(const void*)stroke_line, draw_shape,
(const void*)stroke_rect, draw_string,
(const void*)fill_rect, draw_pixels,
(const void*)stroke_round_rect, // 5 draw_picture,
(const void*)fill_round_rect, set_clipping_rects,
(const void*)stroke_bezier, clip_to_picture,
(const void*)fill_bezier, push_state,
(const void*)stroke_arc, pop_state,
(const void*)fill_arc, // 10 enter_state_change,
(const void*)stroke_ellipse, exit_state_change,
(const void*)fill_ellipse, enter_font_state,
(const void*)stroke_polygon, exit_font_state,
(const void*)fill_polygon, set_origin,
(const void*)stroke_shape, // 15 set_pen_location,
(const void*)fill_shape, set_drawing_mode,
(const void*)draw_string, set_line_mode,
(const void*)draw_pixels, set_pen_size,
(const void*)draw_picture, set_fore_color,
(const void*)set_clipping_rects, // 20 set_back_color,
(const void*)clip_to_picture, set_stipple_pattern,
(const void*)push_state, set_scale,
(const void*)pop_state, set_font_family,
(const void*)enter_state_change, set_font_style,
(const void*)exit_state_change, // 25 set_font_spacing,
(const void*)enter_font_state, set_font_size,
(const void*)exit_font_state, set_font_rotation,
(const void*)set_origin, set_font_encoding,
(const void*)set_pen_location, set_font_flags,
(const void*)set_drawing_mode, // 30 set_font_shear,
(const void*)set_line_mode, set_font_face,
(const void*)set_pen_size, set_blending_mode
(const void*)set_fore_color,
(const void*)set_back_color,
(const void*)set_stipple_pattern, // 35
(const void*)set_scale,
(const void*)set_font_family,
(const void*)set_font_style,
(const void*)set_font_spacing,
(const void*)set_font_size, // 40
(const void*)set_font_rotate,
(const void*)set_font_encoding,
(const void*)set_font_flags,
(const void*)set_font_shear,
(const void*)reserved, // 45
(const void*)set_font_face,
(const void*)set_blending_mode // 47
}; };
@@ -1078,8 +1007,8 @@ ServerPicture::Play(DrawingContext* target)
BPrivate::PicturePlayer player(mallocIO->Buffer(), BPrivate::PicturePlayer player(mallocIO->Buffer(),
mallocIO->BufferLength(), PictureList::Private(fPictures).AsBList()); mallocIO->BufferLength(), PictureList::Private(fPictures).AsBList());
player.Play(const_cast<void**>(kTableEntries), player.Play(kPicturePlayerCallbacks, sizeof(kPicturePlayerCallbacks),
sizeof(kTableEntries) / sizeof(void*), target); target);
} }