* Painter uses the line_cap and join_mode settings of DrawState
* Painter implements DrawShape for stroking and filling BShape data * Painter uses clipping to avoid problems with huge coordinates, the R5 app_server can be crashed by this. -> this should be added to more places as well like text rendering * DrawingEngine uses the Painter to draw BShape data git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14735 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -133,7 +133,7 @@ public:
|
|||||||
|
|
||||||
void DrawShape( const BRect &bounds,
|
void DrawShape( const BRect &bounds,
|
||||||
const int32 &opcount,
|
const int32 &opcount,
|
||||||
const int32 *oplist,
|
const uint32 *oplist,
|
||||||
const int32 &ptcount,
|
const int32 &ptcount,
|
||||||
const BPoint *ptlist,
|
const BPoint *ptlist,
|
||||||
const DrawState *d,
|
const DrawState *d,
|
||||||
|
|||||||
@@ -808,14 +808,21 @@ DrawingEngine::DrawRoundRect(BRect r, const float &xrad,
|
|||||||
|
|
||||||
// DrawShape
|
// DrawShape
|
||||||
void
|
void
|
||||||
DrawingEngine::DrawShape(const BRect &bounds, const int32 &opcount,
|
DrawingEngine::DrawShape(const BRect& bounds, const int32& opCount,
|
||||||
const int32 *oplist, const int32 &ptcount,
|
const uint32* opList, const int32& ptCount,
|
||||||
const BPoint *ptlist, const DrawState *d,
|
const BPoint* ptList, const DrawState* d,
|
||||||
bool filled)
|
bool filled)
|
||||||
{
|
{
|
||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
|
fGraphicsCard->HideSoftwareCursor();
|
||||||
|
|
||||||
printf("DrawingEngine::DrawShape() - what is this stuff that gets passed here?\n");
|
fPainter->SetDrawState(d);
|
||||||
|
BRect touched = fPainter->DrawShape(opCount, opList,
|
||||||
|
ptCount, ptList,
|
||||||
|
filled);
|
||||||
|
|
||||||
|
fGraphicsCard->Invalidate(touched);
|
||||||
|
fGraphicsCard->ShowSoftwareCursor();
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,11 @@
|
|||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <GraphicsDefs.h>
|
#include <GraphicsDefs.h>
|
||||||
#include <Region.h>
|
#include <Region.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
#include <agg_bezier_arc.h>
|
#include <agg_bezier_arc.h>
|
||||||
#include <agg_bounding_rect.h>
|
#include <agg_bounding_rect.h>
|
||||||
|
#include <agg_conv_clip_polygon.h>
|
||||||
#include <agg_conv_curve.h>
|
#include <agg_conv_curve.h>
|
||||||
#include <agg_conv_stroke.h>
|
#include <agg_conv_stroke.h>
|
||||||
#include <agg_ellipse.h>
|
#include <agg_ellipse.h>
|
||||||
@@ -31,7 +33,6 @@
|
|||||||
#include "DrawingModeFactory.h"
|
#include "DrawingModeFactory.h"
|
||||||
#include "PatternHandler.h"
|
#include "PatternHandler.h"
|
||||||
#include "RenderingBuffer.h"
|
#include "RenderingBuffer.h"
|
||||||
#include "ShapeConverter.h"
|
|
||||||
#include "ServerBitmap.h"
|
#include "ServerBitmap.h"
|
||||||
#include "ServerFont.h"
|
#include "ServerFont.h"
|
||||||
|
|
||||||
@@ -77,6 +78,7 @@ Painter::Painter()
|
|||||||
fFontRendererBin(NULL),
|
fFontRendererBin(NULL),
|
||||||
fLineProfile(),
|
fLineProfile(),
|
||||||
fSubpixelPrecise(false),
|
fSubpixelPrecise(false),
|
||||||
|
|
||||||
fPenSize(1.0),
|
fPenSize(1.0),
|
||||||
fClippingRegion(new BRegion()),
|
fClippingRegion(new BRegion()),
|
||||||
fValidClipping(false),
|
fValidClipping(false),
|
||||||
@@ -85,6 +87,10 @@ Painter::Painter()
|
|||||||
// fAlphaSrcMode(B_CONSTANT_ALPHA),
|
// fAlphaSrcMode(B_CONSTANT_ALPHA),
|
||||||
fAlphaFncMode(B_ALPHA_OVERLAY),
|
fAlphaFncMode(B_ALPHA_OVERLAY),
|
||||||
fPenLocation(0.0, 0.0),
|
fPenLocation(0.0, 0.0),
|
||||||
|
fLineCapMode(B_BUTT_CAP),
|
||||||
|
fLineJoinMode(B_MITER_JOIN),
|
||||||
|
fMiterLimit(B_DEFAULT_MITER_LIMIT),
|
||||||
|
|
||||||
fDrawingModeFactory(new DrawingModeFactory()),
|
fDrawingModeFactory(new DrawingModeFactory()),
|
||||||
fPatternHandler(new PatternHandler()),
|
fPatternHandler(new PatternHandler()),
|
||||||
fTextRenderer(new AGGTextRenderer())
|
fTextRenderer(new AGGTextRenderer())
|
||||||
@@ -191,10 +197,13 @@ Painter::SetDrawState(const DrawState* data)
|
|||||||
(data->GetDrawingMode() == B_OP_ALPHA && (data->AlphaSrcMode() != fAlphaSrcMode ||
|
(data->GetDrawingMode() == B_OP_ALPHA && (data->AlphaSrcMode() != fAlphaSrcMode ||
|
||||||
data->AlphaFncMode() != fAlphaFncMode));
|
data->AlphaFncMode() != fAlphaFncMode));
|
||||||
|
|
||||||
fDrawingMode = data->GetDrawingMode();
|
fDrawingMode = data->GetDrawingMode();
|
||||||
fAlphaSrcMode = data->AlphaSrcMode();
|
fAlphaSrcMode = data->AlphaSrcMode();
|
||||||
fAlphaFncMode = data->AlphaFncMode();
|
fAlphaFncMode = data->AlphaFncMode();
|
||||||
fPatternHandler->SetPattern(data->GetPattern());
|
fPatternHandler->SetPattern(data->GetPattern());
|
||||||
|
fLineCapMode = data->LineCapMode();
|
||||||
|
fLineJoinMode = data->LineJoinMode();
|
||||||
|
fMiterLimit = data->MiterLimit();
|
||||||
|
|
||||||
if (updateDrawingMode)
|
if (updateDrawingMode)
|
||||||
_UpdateDrawingMode();
|
_UpdateDrawingMode();
|
||||||
@@ -533,18 +542,81 @@ Painter::FillBezier(const BPoint* controlPoints) const
|
|||||||
return _FillPath(path);
|
return _FillPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// StrokeShape
|
// this comes from Shape.cpp
|
||||||
BRect
|
// code duplication ahead...
|
||||||
Painter::StrokeShape(/*const */BShape* shape) const
|
#define OP_LINETO 0x10000000
|
||||||
{
|
#define OP_BEZIERTO 0x20000000
|
||||||
return _DrawShape(shape, false);
|
#define OP_CLOSE 0x40000000
|
||||||
}
|
#define OP_MOVETO 0x80000000
|
||||||
|
|
||||||
// FillShape
|
// DrawShape
|
||||||
BRect
|
BRect
|
||||||
Painter::FillShape(/*const */BShape* shape) const
|
Painter::DrawShape(const int32& opCount, const uint32* opList,
|
||||||
|
const int32& ptCount, const BPoint* points,
|
||||||
|
bool filled) const
|
||||||
{
|
{
|
||||||
return _DrawShape(shape, true);
|
CHECK_CLIPPING
|
||||||
|
|
||||||
|
agg::path_storage path;
|
||||||
|
for (int32 i = 0; i < opCount; i++) {
|
||||||
|
switch (opList[i] & 0xFF000000) {
|
||||||
|
case OP_LINETO: {
|
||||||
|
int32 count = opList[i] & 0x00FFFFFF;
|
||||||
|
while (count--) {
|
||||||
|
path.line_to(points->x, points->y);
|
||||||
|
points++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (OP_MOVETO | OP_LINETO): {
|
||||||
|
int32 count = opList[i] & 0x00FFFFFF;
|
||||||
|
path.move_to(points->x, points->y);
|
||||||
|
points++;
|
||||||
|
// execute "line to(s)"
|
||||||
|
while (count--) {
|
||||||
|
path.line_to(points->x, points->y);
|
||||||
|
points++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_BEZIERTO: {
|
||||||
|
int32 count = opList[i] & 0x00FFFFFF;
|
||||||
|
while (count) {
|
||||||
|
path.curve4(points[0].x, points[0].y,
|
||||||
|
points[1].x, points[1].y,
|
||||||
|
points[2].x, points[2].y);
|
||||||
|
points += 3;
|
||||||
|
count -= 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (OP_MOVETO | OP_BEZIERTO): {
|
||||||
|
int32 count = opList[i] & 0x00FFFFFF;
|
||||||
|
// execute "move to"
|
||||||
|
path.move_to(points->x, points->y);
|
||||||
|
points++;
|
||||||
|
// execute "bezier to(s)"
|
||||||
|
while (count) {
|
||||||
|
path.curve4(points[0].x, points[0].y,
|
||||||
|
points[1].x, points[1].y,
|
||||||
|
points[2].x, points[2].y);
|
||||||
|
points += 3;
|
||||||
|
count -= 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_CLOSE:
|
||||||
|
case OP_CLOSE | OP_LINETO | OP_BEZIERTO: {
|
||||||
|
path.close_polygon();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
agg::conv_curve<agg::path_storage> curve(path);
|
||||||
|
if (filled)
|
||||||
|
return _FillPath(curve);
|
||||||
|
else
|
||||||
|
return _StrokePath(curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
// StrokeRect
|
// StrokeRect
|
||||||
@@ -1239,27 +1311,6 @@ Painter::_DrawEllipse(BPoint center, float xRadius, float yRadius,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _DrawShape
|
|
||||||
inline BRect
|
|
||||||
Painter::_DrawShape(/*const */BShape* shape, bool fill) const
|
|
||||||
{
|
|
||||||
CHECK_CLIPPING
|
|
||||||
|
|
||||||
// TODO: untested
|
|
||||||
agg::path_storage path;
|
|
||||||
ShapeConverter converter(&path);
|
|
||||||
|
|
||||||
// offset locations to center of pixels
|
|
||||||
converter.TranslateBy(BPoint(0.5, 0.5));
|
|
||||||
|
|
||||||
converter.Iterate(shape);
|
|
||||||
|
|
||||||
if (fill)
|
|
||||||
return _FillPath(path);
|
|
||||||
else
|
|
||||||
return _StrokePath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _DrawPolygon
|
// _DrawPolygon
|
||||||
inline BRect
|
inline BRect
|
||||||
Painter::_DrawPolygon(const BPoint* ptArray, int32 numPts,
|
Painter::_DrawPolygon(const BPoint* ptArray, int32 numPts,
|
||||||
@@ -1463,6 +1514,37 @@ Painter::_BoundingBox(VertexSource& path) const
|
|||||||
return BRect(left, top, right, bottom);
|
return BRect(left, top, right, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// agg_line_cap_mode_for
|
||||||
|
inline agg::line_cap_e
|
||||||
|
agg_line_cap_mode_for(cap_mode mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case B_BUTT_CAP:
|
||||||
|
return agg::butt_cap;
|
||||||
|
case B_SQUARE_CAP:
|
||||||
|
return agg::square_cap;
|
||||||
|
case B_ROUND_CAP:
|
||||||
|
return agg::round_cap;
|
||||||
|
}
|
||||||
|
return agg::butt_cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// agg_line_join_mode_for
|
||||||
|
inline agg::line_join_e
|
||||||
|
agg_line_join_mode_for(join_mode mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case B_MITER_JOIN:
|
||||||
|
return agg::miter_join;
|
||||||
|
case B_ROUND_JOIN:
|
||||||
|
return agg::round_join;
|
||||||
|
case B_BEVEL_JOIN:
|
||||||
|
case B_BUTT_JOIN: // ??
|
||||||
|
case B_SQUARE_JOIN: // ??
|
||||||
|
return agg::bevel_join;
|
||||||
|
}
|
||||||
|
return agg::miter_join;
|
||||||
|
}
|
||||||
|
|
||||||
// _StrokePath
|
// _StrokePath
|
||||||
template<class VertexSource>
|
template<class VertexSource>
|
||||||
@@ -1474,20 +1556,23 @@ Painter::_StrokePath(VertexSource& path) const
|
|||||||
#else
|
#else
|
||||||
// if (fPenSize > 1.0) {
|
// if (fPenSize > 1.0) {
|
||||||
agg::conv_stroke<VertexSource> stroke(path);
|
agg::conv_stroke<VertexSource> stroke(path);
|
||||||
// TODO: Investigate this for shapes. Maybe we are supposed to
|
|
||||||
// use the settings from DrawState! Would make some sense!
|
|
||||||
// stroke.line_join(agg::round_join);
|
|
||||||
// stroke.line_cap(agg::butt_cap);
|
|
||||||
stroke.width(fPenSize);
|
stroke.width(fPenSize);
|
||||||
|
|
||||||
// special case line width = 1 with square caps
|
// special case line width = 1 with square caps
|
||||||
// this has a couple of advantages and it looks
|
// this has a couple of advantages and it looks
|
||||||
// like this is also the R5 behaviour.
|
// like this is also the R5 behaviour.
|
||||||
if (fPenSize == 1.0)
|
if (fPenSize == 1.0 && fLineCapMode == B_BUTT_CAP) {
|
||||||
stroke.line_cap(agg::square_cap);
|
stroke.line_cap(agg::square_cap);
|
||||||
|
} else {
|
||||||
|
stroke.line_cap(agg_line_cap_mode_for(fLineCapMode));
|
||||||
|
}
|
||||||
|
stroke.line_join(agg_line_join_mode_for(fLineJoinMode));
|
||||||
|
stroke.miter_limit(fMiterLimit);
|
||||||
|
|
||||||
fRasterizer->reset();
|
fRasterizer->reset();
|
||||||
fRasterizer->add_path(stroke);
|
agg::conv_clip_polygon<agg::conv_stroke<VertexSource> > clippedPath(stroke);
|
||||||
|
clippedPath.clip_box(-500, -500, fBuffer->width() + 500, fBuffer->height() + 500);
|
||||||
|
fRasterizer->add_path(clippedPath);
|
||||||
agg::render_scanlines(*fRasterizer, *fScanline, *fRenderer);
|
agg::render_scanlines(*fRasterizer, *fScanline, *fRenderer);
|
||||||
// } else {
|
// } else {
|
||||||
// TODO: update to AGG 2.3 to get rid of the remaining problems:
|
// TODO: update to AGG 2.3 to get rid of the remaining problems:
|
||||||
@@ -1509,9 +1594,11 @@ BRect
|
|||||||
Painter::_FillPath(VertexSource& path) const
|
Painter::_FillPath(VertexSource& path) const
|
||||||
{
|
{
|
||||||
fRasterizer->reset();
|
fRasterizer->reset();
|
||||||
fRasterizer->add_path(path);
|
agg::conv_clip_polygon<VertexSource> clippedPath(path);
|
||||||
|
clippedPath.clip_box(-500, -500, fBuffer->width() + 500, fBuffer->height() + 500);
|
||||||
|
fRasterizer->add_path(clippedPath);
|
||||||
agg::render_scanlines(*fRasterizer, *fScanline, *fRenderer);
|
agg::render_scanlines(*fRasterizer, *fScanline, *fRenderer);
|
||||||
|
|
||||||
return _Clipped(_BoundingBox(path));
|
return _Clipped(_BoundingBox(clippedPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class PatternHandler;
|
|||||||
class RenderingBuffer;
|
class RenderingBuffer;
|
||||||
class ServerBitmap;
|
class ServerBitmap;
|
||||||
class ServerFont;
|
class ServerFont;
|
||||||
|
class Transformable;
|
||||||
|
|
||||||
// TODO: API transition:
|
// TODO: API transition:
|
||||||
// * most all functions should take a DrawState* context parameter instead
|
// * most all functions should take a DrawState* context parameter instead
|
||||||
@@ -123,10 +124,11 @@ class Painter {
|
|||||||
BRect FillBezier( const BPoint* controlPoints) const;
|
BRect FillBezier( const BPoint* controlPoints) const;
|
||||||
|
|
||||||
// shapes
|
// shapes
|
||||||
BRect StrokeShape( /*const */BShape* shape) const;
|
BRect DrawShape( const int32& opCount,
|
||||||
|
const uint32* opList,
|
||||||
BRect FillShape( /*const */BShape* shape) const;
|
const int32& ptCount,
|
||||||
|
const BPoint* ptList,
|
||||||
|
bool filled) const;
|
||||||
|
|
||||||
// rects
|
// rects
|
||||||
BRect StrokeRect( const BRect& r) const;
|
BRect StrokeRect( const BRect& r) const;
|
||||||
@@ -236,8 +238,6 @@ class Painter {
|
|||||||
float xRadius,
|
float xRadius,
|
||||||
float yRadius,
|
float yRadius,
|
||||||
bool fill) const;
|
bool fill) const;
|
||||||
BRect _DrawShape( /*const */BShape* shape,
|
|
||||||
bool fill) const;
|
|
||||||
BRect _DrawPolygon( const BPoint* ptArray,
|
BRect _DrawPolygon( const BPoint* ptArray,
|
||||||
int32 numPts,
|
int32 numPts,
|
||||||
bool closed,
|
bool closed,
|
||||||
@@ -292,6 +292,9 @@ class Painter {
|
|||||||
source_alpha fAlphaSrcMode;
|
source_alpha fAlphaSrcMode;
|
||||||
alpha_function fAlphaFncMode;
|
alpha_function fAlphaFncMode;
|
||||||
BPoint fPenLocation;
|
BPoint fPenLocation;
|
||||||
|
cap_mode fLineCapMode;
|
||||||
|
join_mode fLineJoinMode;
|
||||||
|
float fMiterLimit;
|
||||||
|
|
||||||
DrawingModeFactory* fDrawingModeFactory;
|
DrawingModeFactory* fDrawingModeFactory;
|
||||||
PatternHandler* fPatternHandler;
|
PatternHandler* fPatternHandler;
|
||||||
|
|||||||
Reference in New Issue
Block a user