massive performance improvements. On my ancient 2xPII 350, the DisplayDriverPainter with the ViewHWInteface is pretty much usable now. It could be even better if app_server culmulated update requests more.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12180 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -64,11 +64,11 @@ class Painter {
|
|||||||
// painting functions
|
// painting functions
|
||||||
|
|
||||||
// lines
|
// lines
|
||||||
void StrokeLine( BPoint a,
|
BRect StrokeLine( BPoint a,
|
||||||
BPoint b,
|
BPoint b,
|
||||||
const pattern& p = B_SOLID_HIGH);
|
const pattern& p = B_SOLID_HIGH);
|
||||||
|
|
||||||
void StrokeLine( BPoint b,
|
BRect StrokeLine( BPoint b,
|
||||||
const pattern& p = B_SOLID_HIGH);
|
const pattern& p = B_SOLID_HIGH);
|
||||||
|
|
||||||
// return true if the line was either vertical or horizontal
|
// return true if the line was either vertical or horizontal
|
||||||
@@ -115,14 +115,14 @@ class Painter {
|
|||||||
|
|
||||||
|
|
||||||
// rects
|
// rects
|
||||||
void StrokeRect( const BRect& r,
|
BRect StrokeRect( const BRect& r,
|
||||||
const pattern& p = B_SOLID_HIGH) const;
|
const pattern& p = B_SOLID_HIGH) const;
|
||||||
|
|
||||||
// strokes a one pixel wide solid rect, no blending
|
// strokes a one pixel wide solid rect, no blending
|
||||||
void StrokeRect( const BRect& r,
|
void StrokeRect( const BRect& r,
|
||||||
const rgb_color& c) const;
|
const rgb_color& c) const;
|
||||||
|
|
||||||
void FillRect( const BRect& r,
|
BRect FillRect( const BRect& r,
|
||||||
const pattern& p = B_SOLID_HIGH) const;
|
const pattern& p = B_SOLID_HIGH) const;
|
||||||
|
|
||||||
// fills a solid rect with color c, no blending
|
// fills a solid rect with color c, no blending
|
||||||
@@ -207,6 +207,9 @@ class Painter {
|
|||||||
uint32 length,
|
uint32 length,
|
||||||
const BPoint& baseLine) const;
|
const BPoint& baseLine) const;
|
||||||
|
|
||||||
|
inline BRect ClipRect(const BRect& rect) const
|
||||||
|
{ return _Clipped(rect); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _MakeEmpty();
|
void _MakeEmpty();
|
||||||
|
|
||||||
@@ -218,6 +221,7 @@ class Painter {
|
|||||||
float _Transform(const float& width) const;
|
float _Transform(const float& width) const;
|
||||||
void _Transform(BRect* rect) const;
|
void _Transform(BRect* rect) const;
|
||||||
BRect _Transform(const BRect& rect) const;
|
BRect _Transform(const BRect& rect) const;
|
||||||
|
BRect _Clipped(const BRect& rect) const;
|
||||||
|
|
||||||
void _RebuildClipping();
|
void _RebuildClipping();
|
||||||
|
|
||||||
@@ -258,10 +262,14 @@ class Painter {
|
|||||||
|
|
||||||
|
|
||||||
template<class VertexSource>
|
template<class VertexSource>
|
||||||
void _StrokePath(VertexSource& path,
|
BRect _BoundingBox(VertexSource& path) const;
|
||||||
|
|
||||||
|
template<class VertexSource>
|
||||||
|
BRect _StrokePath(VertexSource& path,
|
||||||
const pattern& p) const;
|
const pattern& p) const;
|
||||||
template<class VertexSource>
|
template<class VertexSource>
|
||||||
void _FillPath(VertexSource& path,
|
BRect _FillPath(VertexSource& path,
|
||||||
|
|
||||||
const pattern& p) const;
|
const pattern& p) const;
|
||||||
|
|
||||||
void _SetPattern(const pattern& p) const;
|
void _SetPattern(const pattern& p) const;
|
||||||
|
|||||||
@@ -460,7 +460,6 @@ printf("region: %ld, rect: %ld, offset(%ld, %ld)\n", i, j, xOffset, yOffset);
|
|||||||
if (void* rectCopy = rectList.ItemAt(i))
|
if (void* rectCopy = rectList.ItemAt(i))
|
||||||
free(rectCopy);
|
free(rectCopy);
|
||||||
}
|
}
|
||||||
//printf("CopyRegionList(): %lld\n", system_time() - now);
|
|
||||||
|
|
||||||
fGraphicsCard->Invalidate(updateRect);
|
fGraphicsCard->Invalidate(updateRect);
|
||||||
|
|
||||||
@@ -549,9 +548,9 @@ DisplayDriverPainter::FillRect(const BRect &r, const RGBColor &color)
|
|||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
|
|
||||||
fPainter->SetHighColor(color);
|
fPainter->SetHighColor(color);
|
||||||
fPainter->FillRect(r);
|
BRect touched = fPainter->FillRect(r);
|
||||||
|
|
||||||
fGraphicsCard->Invalidate(r);
|
fGraphicsCard->Invalidate(touched);
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
@@ -564,9 +563,9 @@ DisplayDriverPainter::FillRect(const BRect &r, const DrawData *d)
|
|||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
|
|
||||||
fPainter->SetDrawData(d);
|
fPainter->SetDrawData(d);
|
||||||
fPainter->FillRect(r);
|
BRect touched = fPainter->FillRect(r);
|
||||||
|
|
||||||
fGraphicsCard->Invalidate(r);
|
fGraphicsCard->Invalidate(touched);
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
@@ -706,10 +705,17 @@ DisplayDriverPainter::StrokeEllipse(const BRect &r, const DrawData *d)
|
|||||||
void
|
void
|
||||||
DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, const RGBColor &color)
|
DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, const RGBColor &color)
|
||||||
{
|
{
|
||||||
|
if (Lock()) {
|
||||||
|
if (!fPainter->StraightLine(start, end, color.GetColor32())) {
|
||||||
DrawData d;
|
DrawData d;
|
||||||
d.highcolor = color;
|
d.highcolor = color;
|
||||||
d.draw_mode = B_OP_COPY;
|
d.draw_mode = B_OP_COPY;
|
||||||
StrokeLine(start, end, &d);
|
StrokeLine(start, end, &d);
|
||||||
|
} else {
|
||||||
|
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(start, end)));
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StrokeLine
|
// StrokeLine
|
||||||
@@ -719,10 +725,9 @@ DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, const D
|
|||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
|
|
||||||
fPainter->SetDrawData(d);
|
fPainter->SetDrawData(d);
|
||||||
fPainter->StrokeLine(start, end);
|
BRect touched = fPainter->StrokeLine(start, end);
|
||||||
|
|
||||||
BRect r(start, end);
|
fGraphicsCard->Invalidate(touched);
|
||||||
fGraphicsCard->Invalidate(r);
|
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
@@ -768,7 +773,6 @@ void
|
|||||||
DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color)
|
DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color)
|
||||||
{
|
{
|
||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
|
|
||||||
fPainter->StrokeRect(r, color.GetColor32());
|
fPainter->StrokeRect(r, color.GetColor32());
|
||||||
|
|
||||||
fGraphicsCard->Invalidate(BRect(r.left, r.top, r.right, r.top));
|
fGraphicsCard->Invalidate(BRect(r.left, r.top, r.right, r.top));
|
||||||
@@ -787,9 +791,9 @@ DisplayDriverPainter::StrokeRect(const BRect &r, const DrawData *d)
|
|||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
|
|
||||||
fPainter->SetDrawData(d);
|
fPainter->SetDrawData(d);
|
||||||
fPainter->StrokeRect(r);
|
BRect touched = fPainter->StrokeRect(r);
|
||||||
|
|
||||||
fGraphicsCard->Invalidate(r);
|
fGraphicsCard->Invalidate(touched);
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
@@ -803,13 +807,11 @@ DisplayDriverPainter::StrokeRegion(BRegion& r, const DrawData *d)
|
|||||||
|
|
||||||
fPainter->SetDrawData(d);
|
fPainter->SetDrawData(d);
|
||||||
|
|
||||||
BRect invalid = r.RectAt(0);
|
BRect invalid = fPainter->StrokeRect(r.RectAt(0));
|
||||||
fPainter->StrokeRect(invalid);
|
|
||||||
|
|
||||||
int32 count = r.CountRects();
|
int32 count = r.CountRects();
|
||||||
for (int32 i = 1; i < count; i++) {
|
for (int32 i = 1; i < count; i++) {
|
||||||
fPainter->StrokeRect(r.RectAt(i));
|
invalid = invalid | fPainter->StrokeRect(r.RectAt(i));
|
||||||
invalid = invalid | r.RectAt(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fGraphicsCard->Invalidate(invalid);
|
fGraphicsCard->Invalidate(invalid);
|
||||||
@@ -885,6 +887,7 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length,
|
|||||||
const BPoint &pt, DrawData *d)
|
const BPoint &pt, DrawData *d)
|
||||||
{
|
{
|
||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
|
|
||||||
fPainter->SetDrawData(d);
|
fPainter->SetDrawData(d);
|
||||||
|
|
||||||
BRect boundingBox = fPainter->DrawString(string, length, pt);
|
BRect boundingBox = fPainter->DrawString(string, length, pt);
|
||||||
|
|||||||
@@ -4,9 +4,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
|
#include <GraphicsDefs.h>
|
||||||
#include <Region.h>
|
#include <Region.h>
|
||||||
|
|
||||||
#include <agg_bezier_arc.h>
|
#include <agg_bezier_arc.h>
|
||||||
|
#include <agg_bounding_rect.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>
|
||||||
@@ -199,18 +201,22 @@ Painter::SetLowColor(const rgb_color& color)
|
|||||||
void
|
void
|
||||||
Painter::SetScale(float scale)
|
Painter::SetScale(float scale)
|
||||||
{
|
{
|
||||||
|
if (fScale != scale) {
|
||||||
fScale = scale;
|
fScale = scale;
|
||||||
_RebuildClipping();
|
_RebuildClipping();
|
||||||
_UpdateLineWidth();
|
_UpdateLineWidth();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetPenSize
|
// SetPenSize
|
||||||
void
|
void
|
||||||
Painter::SetPenSize(float size)
|
Painter::SetPenSize(float size)
|
||||||
{
|
{
|
||||||
|
if (fPenSize != size) {
|
||||||
fPenSize = size;
|
fPenSize = size;
|
||||||
_UpdateLineWidth();
|
_UpdateLineWidth();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetOrigin
|
// SetOrigin
|
||||||
void
|
void
|
||||||
@@ -245,6 +251,8 @@ void
|
|||||||
Painter::SetBlendingMode(source_alpha alphaSrcMode, alpha_function alphaFncMode)
|
Painter::SetBlendingMode(source_alpha alphaSrcMode, alpha_function alphaFncMode)
|
||||||
{
|
{
|
||||||
if (fAlphaSrcMode != alphaSrcMode || fAlphaFncMode != alphaFncMode) {
|
if (fAlphaSrcMode != alphaSrcMode || fAlphaFncMode != alphaFncMode) {
|
||||||
|
fAlphaSrcMode = alphaSrcMode;
|
||||||
|
fAlphaFncMode = alphaFncMode;
|
||||||
if (fDrawingMode == B_OP_ALPHA && fPixelFormat) {
|
if (fDrawingMode == B_OP_ALPHA && fPixelFormat) {
|
||||||
fPixelFormat->set_drawing_mode(DrawingModeFactory::DrawingModeFor(fDrawingMode,
|
fPixelFormat->set_drawing_mode(DrawingModeFactory::DrawingModeFor(fDrawingMode,
|
||||||
fAlphaSrcMode,
|
fAlphaSrcMode,
|
||||||
@@ -284,12 +292,14 @@ Painter::SetFont(const ServerFont& font)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
// StrokeLine
|
// StrokeLine
|
||||||
void
|
BRect
|
||||||
Painter::StrokeLine(BPoint a, BPoint b, const pattern& p)
|
Painter::StrokeLine(BPoint a, BPoint b, const pattern& p)
|
||||||
{
|
{
|
||||||
_Transform(&a);
|
_Transform(&a);
|
||||||
_Transform(&b);
|
_Transform(&b);
|
||||||
|
|
||||||
|
BRect touched(a, b);
|
||||||
|
|
||||||
// first, try an optimized version
|
// first, try an optimized version
|
||||||
float penSize = _Transform(fPenSize);
|
float penSize = _Transform(fPenSize);
|
||||||
if (penSize == 1.0 &&
|
if (penSize == 1.0 &&
|
||||||
@@ -298,30 +308,31 @@ Painter::StrokeLine(BPoint a, BPoint b, const pattern& p)
|
|||||||
if (pat == B_SOLID_HIGH &&
|
if (pat == B_SOLID_HIGH &&
|
||||||
StraightLine(a, b, fPatternHandler->HighColor().GetColor32())) {
|
StraightLine(a, b, fPatternHandler->HighColor().GetColor32())) {
|
||||||
SetPenLocation(b);
|
SetPenLocation(b);
|
||||||
return;
|
return _Clipped(touched);
|
||||||
} else if (pat == B_SOLID_LOW &&
|
} else if (pat == B_SOLID_LOW &&
|
||||||
StraightLine(a, b, fPatternHandler->LowColor().GetColor32())) {
|
StraightLine(a, b, fPatternHandler->LowColor().GetColor32())) {
|
||||||
SetPenLocation(b);
|
SetPenLocation(b);
|
||||||
return;
|
return _Clipped(touched);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
agg::path_storage path;
|
agg::path_storage path;
|
||||||
path.move_to(a.x, a.y);
|
path.move_to(a.x, a.y);
|
||||||
path.line_to(b.x, b.y);
|
path.line_to(b.x, b.y);
|
||||||
|
|
||||||
_StrokePath(path, p);
|
touched = _StrokePath(path, p);
|
||||||
|
|
||||||
SetPenLocation(b);
|
SetPenLocation(b);
|
||||||
|
|
||||||
|
return _Clipped(touched);
|
||||||
}
|
}
|
||||||
|
|
||||||
// StrokeLine
|
// StrokeLine
|
||||||
void
|
BRect
|
||||||
Painter::StrokeLine(BPoint b, const pattern& p)
|
Painter::StrokeLine(BPoint b, const pattern& p)
|
||||||
{
|
{
|
||||||
// TODO: move this function elsewhere
|
// TODO: move this function elsewhere
|
||||||
StrokeLine(fPenLocation, b);
|
return StrokeLine(fPenLocation, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// StraightLine
|
// StraightLine
|
||||||
@@ -486,7 +497,7 @@ Painter::FillShape(/*const */BShape* shape, const pattern& p) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StrokeRect
|
// StrokeRect
|
||||||
void
|
BRect
|
||||||
Painter::StrokeRect(const BRect& r, const pattern& p) const
|
Painter::StrokeRect(const BRect& r, const pattern& p) const
|
||||||
{
|
{
|
||||||
BPoint a(r.left, r.top);
|
BPoint a(r.left, r.top);
|
||||||
@@ -501,13 +512,15 @@ Painter::StrokeRect(const BRect& r, const pattern& p) const
|
|||||||
// TODO: fix me
|
// TODO: fix me
|
||||||
// pattern p = *fPatternHandler->GetR5Pattern();
|
// pattern p = *fPatternHandler->GetR5Pattern();
|
||||||
if (p == B_SOLID_HIGH) {
|
if (p == B_SOLID_HIGH) {
|
||||||
StrokeRect(BRect(a, b),
|
BRect rect(a, b);
|
||||||
|
StrokeRect(rect,
|
||||||
fPatternHandler->HighColor().GetColor32());
|
fPatternHandler->HighColor().GetColor32());
|
||||||
return;
|
return _Clipped(rect);
|
||||||
} else if (p == B_SOLID_LOW) {
|
} else if (p == B_SOLID_LOW) {
|
||||||
StrokeRect(BRect(a, b),
|
BRect rect(a, b);
|
||||||
|
StrokeRect(rect,
|
||||||
fPatternHandler->LowColor().GetColor32());
|
fPatternHandler->LowColor().GetColor32());
|
||||||
return;
|
return _Clipped(rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,7 +531,7 @@ Painter::StrokeRect(const BRect& r, const pattern& p) const
|
|||||||
path.line_to(a.x, b.y);
|
path.line_to(a.x, b.y);
|
||||||
path.close_polygon();
|
path.close_polygon();
|
||||||
|
|
||||||
_StrokePath(path, p);
|
return _StrokePath(path, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// StrokeRect
|
// StrokeRect
|
||||||
@@ -536,7 +549,7 @@ Painter::StrokeRect(const BRect& r, const rgb_color& c) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FillRect
|
// FillRect
|
||||||
void
|
BRect
|
||||||
Painter::FillRect(const BRect& r, const pattern& p) const
|
Painter::FillRect(const BRect& r, const pattern& p) const
|
||||||
{
|
{
|
||||||
BPoint a(r.left, r.top);
|
BPoint a(r.left, r.top);
|
||||||
@@ -548,11 +561,13 @@ Painter::FillRect(const BRect& r, const pattern& p) const
|
|||||||
if (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER) {
|
if (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER) {
|
||||||
pattern pat = *fPatternHandler->GetR5Pattern();
|
pattern pat = *fPatternHandler->GetR5Pattern();
|
||||||
if (pat == B_SOLID_HIGH) {
|
if (pat == B_SOLID_HIGH) {
|
||||||
FillRect(BRect(a, b), fPatternHandler->HighColor().GetColor32());
|
BRect rect(a, b);
|
||||||
return;
|
FillRect(rect, fPatternHandler->HighColor().GetColor32());
|
||||||
|
return _Clipped(rect);
|
||||||
} else if (pat == B_SOLID_LOW) {
|
} else if (pat == B_SOLID_LOW) {
|
||||||
FillRect(BRect(a, b), fPatternHandler->LowColor().GetColor32());
|
BRect rect(a, b);
|
||||||
return;
|
FillRect(rect, fPatternHandler->LowColor().GetColor32());
|
||||||
|
return _Clipped(rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,7 +584,7 @@ Painter::FillRect(const BRect& r, const pattern& p) const
|
|||||||
path.line_to(a.x, b.y);
|
path.line_to(a.x, b.y);
|
||||||
path.close_polygon();
|
path.close_polygon();
|
||||||
|
|
||||||
_FillPath(path, p);
|
return _FillPath(path, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FillRect
|
// FillRect
|
||||||
@@ -771,11 +786,17 @@ Painter::DrawString(const char* utf8String, uint32 length,
|
|||||||
transform.ScaleBy(B_ORIGIN, fScale, fScale);
|
transform.ScaleBy(B_ORIGIN, fScale, fScale);
|
||||||
transform.TranslateBy(fOrigin);
|
transform.TranslateBy(fOrigin);
|
||||||
|
|
||||||
|
BRect clippingFrame;
|
||||||
|
if (fClippingRegion)
|
||||||
|
clippingFrame = _Transform(fClippingRegion->Frame());
|
||||||
|
|
||||||
bounds = fTextRenderer->RenderString(utf8String,
|
bounds = fTextRenderer->RenderString(utf8String,
|
||||||
length,
|
length,
|
||||||
fFontRendererSolid,
|
fFontRendererSolid,
|
||||||
fFontRendererBin,
|
fFontRendererBin,
|
||||||
transform, false,
|
transform,
|
||||||
|
clippingFrame,
|
||||||
|
false,
|
||||||
&fPenLocation);
|
&fPenLocation);
|
||||||
// pen location is not transformed in quite the same way,
|
// pen location is not transformed in quite the same way,
|
||||||
// or transformations would add up
|
// or transformations would add up
|
||||||
@@ -784,9 +805,7 @@ Painter::DrawString(const char* utf8String, uint32 length,
|
|||||||
transform.TranslateBy(baseLine);
|
transform.TranslateBy(baseLine);
|
||||||
transform.Transform(&fPenLocation);
|
transform.Transform(&fPenLocation);
|
||||||
}
|
}
|
||||||
if (bounds.IsValid() && fClippingRegion)
|
return _Clipped(bounds);
|
||||||
bounds = bounds & _Transform(fClippingRegion->Frame());
|
|
||||||
return bounds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawString
|
// DrawString
|
||||||
@@ -885,11 +904,12 @@ Painter::BoundingBox(const char* utf8String, uint32 length,
|
|||||||
Transformable transform;
|
Transformable transform;
|
||||||
transform.TranslateBy(baseLine);
|
transform.TranslateBy(baseLine);
|
||||||
|
|
||||||
|
BRect dummy;
|
||||||
return fTextRenderer->RenderString(utf8String,
|
return fTextRenderer->RenderString(utf8String,
|
||||||
length,
|
length,
|
||||||
fFontRendererSolid,
|
fFontRendererSolid,
|
||||||
fFontRendererBin,
|
fFontRendererBin,
|
||||||
transform, true);
|
transform, dummy, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
@@ -1008,6 +1028,17 @@ Painter::_Transform(const BRect& rect) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _Clipped
|
||||||
|
BRect
|
||||||
|
Painter::_Clipped(const BRect& rect) const
|
||||||
|
{
|
||||||
|
if (rect.IsValid() && fClippingRegion)
|
||||||
|
return rect & _Transform(fClippingRegion->Frame());
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
// _RebuildClipping
|
// _RebuildClipping
|
||||||
void
|
void
|
||||||
Painter::_RebuildClipping()
|
Painter::_RebuildClipping()
|
||||||
@@ -1320,9 +1351,24 @@ Painter::_InvertRect32(BRect r) const
|
|||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
template<class VertexSource>
|
||||||
|
BRect
|
||||||
|
Painter::_BoundingBox(VertexSource& path) const
|
||||||
|
{
|
||||||
|
double left = 0.0;
|
||||||
|
double top = 0.0;
|
||||||
|
double right = -1.0;
|
||||||
|
double bottom = -1.0;
|
||||||
|
uint32 pathID[1];
|
||||||
|
pathID[0] = 0;
|
||||||
|
agg::bounding_rect(path, pathID, 0, 1, &left, &top, &right, &bottom);
|
||||||
|
return BRect(left, top, right, bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// _StrokePath
|
// _StrokePath
|
||||||
template<class VertexSource>
|
template<class VertexSource>
|
||||||
void
|
BRect
|
||||||
Painter::_StrokePath(VertexSource& path, const pattern& p) const
|
Painter::_StrokePath(VertexSource& path, const pattern& p) const
|
||||||
{
|
{
|
||||||
// We're now used by app_server and SetDrawData() was called prior to
|
// We're now used by app_server and SetDrawData() was called prior to
|
||||||
@@ -1345,11 +1391,13 @@ Painter::_StrokePath(VertexSource& path, const pattern& p) const
|
|||||||
#else
|
#else
|
||||||
fOutlineRasterizer->add_path(path);
|
fOutlineRasterizer->add_path(path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return _Clipped(_BoundingBox(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
// _FillPath
|
// _FillPath
|
||||||
template<class VertexSource>
|
template<class VertexSource>
|
||||||
void
|
BRect
|
||||||
Painter::_FillPath(VertexSource& path, const pattern& p) const
|
Painter::_FillPath(VertexSource& path, const pattern& p) const
|
||||||
{
|
{
|
||||||
// We're now used by app_server and SetDrawData() was called prior to
|
// We're now used by app_server and SetDrawData() was called prior to
|
||||||
@@ -1359,24 +1407,25 @@ Painter::_FillPath(VertexSource& path, const pattern& p) const
|
|||||||
|
|
||||||
fRasterizer->add_path(path);
|
fRasterizer->add_path(path);
|
||||||
agg::render_scanlines(*fRasterizer, *fScanline, *fRenderer);
|
agg::render_scanlines(*fRasterizer, *fScanline, *fRenderer);
|
||||||
|
|
||||||
|
return _Clipped(_BoundingBox(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
// _SetPattern
|
// _SetPattern
|
||||||
void
|
void
|
||||||
Painter::_SetPattern(const pattern& p) const
|
Painter::_SetPattern(const pattern& p) const
|
||||||
{
|
{
|
||||||
if (memcmp(&p, fPatternHandler->GetR5Pattern(), sizeof(pattern)) != 0) {
|
if (!(p == *fPatternHandler->GetR5Pattern())) {
|
||||||
// if ((uint64)p != (uint64)*fPatternHandler->GetR5Pattern()) {
|
|
||||||
printf("Painter::_SetPattern()\n");
|
printf("Painter::_SetPattern()\n");
|
||||||
fPatternHandler->SetPattern(p);
|
fPatternHandler->SetPattern(p);
|
||||||
DrawingMode* mode = NULL;
|
DrawingMode* mode = NULL;
|
||||||
if (memcmp(&p, &B_SOLID_HIGH, sizeof(pattern)) == 0) {
|
if (p == B_SOLID_HIGH) {
|
||||||
_SetRendererColor(fPatternHandler->HighColor().GetColor32());
|
_SetRendererColor(fPatternHandler->HighColor().GetColor32());
|
||||||
mode = DrawingModeFactory::DrawingModeFor(fDrawingMode,
|
mode = DrawingModeFactory::DrawingModeFor(fDrawingMode,
|
||||||
fAlphaSrcMode,
|
fAlphaSrcMode,
|
||||||
fAlphaFncMode,
|
fAlphaFncMode,
|
||||||
true);
|
true);
|
||||||
} else if (memcmp(&p, &B_SOLID_LOW, sizeof(pattern)) == 0) {
|
} else if (p == B_SOLID_LOW) {
|
||||||
_SetRendererColor(fPatternHandler->LowColor().GetColor32());
|
_SetRendererColor(fPatternHandler->LowColor().GetColor32());
|
||||||
mode = DrawingModeFactory::DrawingModeFor(fDrawingMode,
|
mode = DrawingModeFactory::DrawingModeFor(fDrawingMode,
|
||||||
fAlphaSrcMode,
|
fAlphaSrcMode,
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ AGGTextRenderer::Archive(BMessage* into, bool deep) const
|
|||||||
bool
|
bool
|
||||||
AGGTextRenderer::SetFont(const ServerFont &font)
|
AGGTextRenderer::SetFont(const ServerFont &font)
|
||||||
{
|
{
|
||||||
// if (fFontEngine.load_font(font, agg::glyph_ren_native_gray8)) {
|
if (fFontEngine.load_font(font, agg::glyph_ren_native_gray8)) {
|
||||||
if (fFontEngine.load_font(font, agg::glyph_ren_outline)) {
|
// if (fFontEngine.load_font(font, agg::glyph_ren_outline)) {
|
||||||
return TextRenderer::SetFont(font);
|
return TextRenderer::SetFont(font);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "font could not be loaded\n");
|
fprintf(stderr, "font could not be loaded\n");
|
||||||
@@ -189,10 +189,11 @@ AGGTextRenderer::RenderString(const char* string,
|
|||||||
font_renderer_solid_type* solidRenderer,
|
font_renderer_solid_type* solidRenderer,
|
||||||
font_renderer_bin_type* binRenderer,
|
font_renderer_bin_type* binRenderer,
|
||||||
const Transformable& transform,
|
const Transformable& transform,
|
||||||
|
BRect clippingFrame,
|
||||||
bool dryRun,
|
bool dryRun,
|
||||||
BPoint* nextCharPos)
|
BPoint* nextCharPos)
|
||||||
{
|
{
|
||||||
fFontEngine.hinting(fHinted);
|
fFontEngine.hinting(false);
|
||||||
fFontEngine.height((int32)(fPtSize));
|
fFontEngine.height((int32)(fPtSize));
|
||||||
fFontEngine.width((int32)(fPtSize));
|
fFontEngine.width((int32)(fPtSize));
|
||||||
|
|
||||||
@@ -237,6 +238,10 @@ AGGTextRenderer::RenderString(const char* string,
|
|||||||
double advanceX = 0.0;
|
double advanceX = 0.0;
|
||||||
double advanceY = 0.0;
|
double advanceY = 0.0;
|
||||||
|
|
||||||
|
// for when we bypass the transformation pipeline
|
||||||
|
BPoint transformOffset(0.0, 0.0);
|
||||||
|
transform.Transform(&transformOffset);
|
||||||
|
|
||||||
for (int32 i = 0; i < dstLength / 2; i++) {
|
for (int32 i = 0; i < dstLength / 2; i++) {
|
||||||
|
|
||||||
// line break
|
// line break
|
||||||
@@ -264,75 +269,68 @@ AGGTextRenderer::RenderString(const char* string,
|
|||||||
x += (fAdvanceScale - 1.0) * fFontEngine.height();
|
x += (fAdvanceScale - 1.0) * fFontEngine.height();
|
||||||
y += advanceY;
|
y += advanceY;
|
||||||
|
|
||||||
|
// calculate bounds
|
||||||
|
const agg::rect& r = glyph->bounds;
|
||||||
|
BRect glyphBounds(r.x1 + x, r.y1 + y, r.x2 + x, r.y2 + y);
|
||||||
|
|
||||||
|
// init the fontmanager and transform glyph bounds
|
||||||
|
if (glyph->data_type != agg::glyph_data_outline) {
|
||||||
|
// we cannot use the transformation pipeline
|
||||||
|
double transformedX = x + transformOffset.x;
|
||||||
|
double transformedY = y + transformOffset.y;
|
||||||
|
fFontManager.init_embedded_adaptors(glyph,
|
||||||
|
transformedX,
|
||||||
|
transformedY);
|
||||||
|
glyphBounds.OffsetBy(transformOffset);
|
||||||
|
} else {
|
||||||
fFontManager.init_embedded_adaptors(glyph, x, y);
|
fFontManager.init_embedded_adaptors(glyph, x, y);
|
||||||
|
glyphBounds = transform.TransformBounds(glyphBounds);
|
||||||
|
}
|
||||||
|
|
||||||
double left = 0.0;
|
// render glyph and update touched area
|
||||||
double top = 0.0;
|
if (!dryRun && clippingFrame.Intersects(glyphBounds)) {
|
||||||
double right = -1.0;
|
|
||||||
double bottom = -1.0;
|
|
||||||
uint32 pathID[1];
|
|
||||||
pathID[0] = 0;
|
|
||||||
|
|
||||||
const agg::rect& r = fFontEngine.bounds();
|
|
||||||
|
|
||||||
switch(glyph->data_type) {
|
switch(glyph->data_type) {
|
||||||
case agg::glyph_data_mono:
|
case agg::glyph_data_mono:
|
||||||
left = r.x1 + x;
|
|
||||||
right = r.x2 + x;
|
|
||||||
top = r.y1 + y;
|
|
||||||
bottom = r.y2 + y;
|
|
||||||
if (!dryRun) {
|
|
||||||
agg::render_scanlines(fFontManager.mono_adaptor(),
|
agg::render_scanlines(fFontManager.mono_adaptor(),
|
||||||
fFontManager.mono_scanline(),
|
fFontManager.mono_scanline(),
|
||||||
*binRenderer);
|
*binRenderer);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case agg::glyph_data_gray8:
|
case agg::glyph_data_gray8:
|
||||||
left = r.x1 + x;
|
|
||||||
right = r.x2 + x;
|
|
||||||
top = r.y1 + y;
|
|
||||||
bottom = r.y2 + y;
|
|
||||||
if (!dryRun) {
|
|
||||||
agg::render_scanlines(fFontManager.gray8_adaptor(),
|
agg::render_scanlines(fFontManager.gray8_adaptor(),
|
||||||
fFontManager.gray8_scanline(),
|
fFontManager.gray8_scanline(),
|
||||||
*solidRenderer);
|
*solidRenderer);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case agg::glyph_data_outline:
|
case agg::glyph_data_outline:
|
||||||
ras.reset();
|
ras.reset();
|
||||||
if(fabs(0.0) <= 0.01) {
|
// NOTE: this function can be easily extended to handle
|
||||||
|
// conversion to contours, to that's why there is a lot of
|
||||||
|
// commented out code, I leave here because I think it
|
||||||
|
// will be needed again.
|
||||||
|
|
||||||
|
// if(fabs(0.0) <= 0.01) {
|
||||||
// For the sake of efficiency skip the
|
// For the sake of efficiency skip the
|
||||||
// contour converter if the weight is about zero.
|
// contour converter if the weight is about zero.
|
||||||
//-----------------------
|
//-----------------------
|
||||||
agg::bounding_rect(ftrans, pathID, 0, 1,
|
|
||||||
&left, &top, &right, &bottom);
|
|
||||||
if (!dryRun)
|
|
||||||
// ras.add_path(fCurves);
|
// ras.add_path(fCurves);
|
||||||
ras.add_path(ftrans);
|
ras.add_path(ftrans);
|
||||||
} else {
|
/* } else {
|
||||||
if (!dryRun)
|
|
||||||
// ras.add_path(fContour);
|
// ras.add_path(fContour);
|
||||||
ras.add_path(ftrans);
|
ras.add_path(ftrans);
|
||||||
agg::bounding_rect(ftrans, pathID, 0, 1,
|
}*/
|
||||||
&left, &top, &right, &bottom);
|
|
||||||
}
|
|
||||||
if (!dryRun) {
|
|
||||||
if (fAntialias) {
|
if (fAntialias) {
|
||||||
agg::render_scanlines(ras, sl, *solidRenderer);
|
agg::render_scanlines(ras, sl, *solidRenderer);
|
||||||
} else {
|
} else {
|
||||||
agg::render_scanlines(ras, sl, *binRenderer);
|
agg::render_scanlines(ras, sl, *binRenderer);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// calculate bounds
|
}
|
||||||
BRect t(left, top, right, bottom);
|
if (glyphBounds.IsValid())
|
||||||
if (t.IsValid())
|
bounds = bounds.IsValid() ? bounds | glyphBounds : glyphBounds;
|
||||||
bounds = bounds.IsValid() ? bounds | t : t;
|
|
||||||
|
|
||||||
// increment pen position
|
// increment pen position
|
||||||
advanceX = fHinted ? floorf(glyph->advance_x + 0.5) : glyph->advance_x;
|
advanceX = fHinted ? floorf(glyph->advance_x + 0.5) : glyph->advance_x;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class AGGTextRenderer : public TextRenderer {
|
|||||||
font_renderer_solid_type* solidRenderer,
|
font_renderer_solid_type* solidRenderer,
|
||||||
font_renderer_bin_type* binRenderer,
|
font_renderer_bin_type* binRenderer,
|
||||||
const Transformable& transform,
|
const Transformable& transform,
|
||||||
|
BRect clippingFrame,
|
||||||
bool dryRun = false,
|
bool dryRun = false,
|
||||||
BPoint* nextCharPos = NULL);
|
BPoint* nextCharPos = NULL);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user