* completed my changes to DrawState handling, the current DrawingState

of the active ViewLayer is now always mirrored in the Painter instance
  of a ServerWindow, so that it doesn't need to be synced on every drawing
  command, this was previously incomplete for font handling
* removed the DrawState parameter from all the DrawingEngine functions
* adjusted ServerWindow and ServerPicture accordingly
* made sure that string related functions used by non-drawing related
  parts (ServerApp, Decorator) don't interfere with the current drawing
  state
* moved AS_SYNC handling from _DispatchViewMessage to _DispatchMessage,
  it is actually a window message and doesn't require fCurrentLayer to
  be valid
* fixed bug #1300, fCurrentLayer was not updated when a ViewLayer was
  deleted by client request which happened to be fCurrentLayer (I am now
  handling it so that the parent becomes the current layer, could be
  wrong)
* AGGTextRenderer is no longer using it's own scanline, which should save
  a few bytes RAM, the Painter already had such an object
* StringWidth() in AGGTextRenderer is now taking the escapement_delta into
  account
* Painter::StrokeLine() doesn't need to check the clipping as much, since
  that is already done in DrawingEngine
* if a ServerWindow message is not handled because fCurrentLayer is NULL,
  a reply is sent in case the messages needs it (client window could
  freeze otherwise, waiting for the reply for ever)
* removed unused AS_SET_FONT and AS_SET_FONT_SIZE
* added automatic RGBColor -> rgb_color conversion to RGBColor.h
* minor cleanup for 80 char/line limit



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21685 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2007-07-22 19:48:27 +00:00
parent d069bd6917
commit 38287e02af
16 changed files with 303 additions and 272 deletions
-2
View File
@@ -212,8 +212,6 @@ enum {
AS_FILL_TRIANGLE, AS_FILL_TRIANGLE,
AS_DRAW_STRING, AS_DRAW_STRING,
AS_SET_FONT,
AS_SET_FONT_SIZE,
AS_SYNC, AS_SYNC,
+8 -5
View File
@@ -639,8 +639,9 @@ DefaultDecorator::_DoLayout()
fMinTabSize += offset + size; fMinTabSize += offset + size;
// fMaxTabSize contains fMinWidth + the width required for the title // fMaxTabSize contains fMinWidth + the width required for the title
fMaxTabSize = fDrawingEngine ? ceilf(fDrawingEngine->StringWidth(Title(), strlen(Title()), fMaxTabSize = fDrawingEngine ?
&fDrawState)) : 0.0; ceilf(fDrawingEngine->StringWidth(Title(), strlen(Title()),
fDrawState.Font())) : 0.0;
if (fMaxTabSize > 0.0) if (fMaxTabSize > 0.0)
fMaxTabSize += fTextOffset; fMaxTabSize += fTextOffset;
fMaxTabSize += fMinTabSize; fMaxTabSize += fMinTabSize;
@@ -967,8 +968,9 @@ DefaultDecorator::_DrawTitle(BRect r)
{ {
STRACE(("_DrawTitle(%f,%f,%f,%f)\n", r.left, r.top, r.right, r.bottom)); STRACE(("_DrawTitle(%f,%f,%f,%f)\n", r.left, r.top, r.right, r.bottom));
fDrawState.SetHighColor(fTextColor); fDrawingEngine->SetHighColor(fTextColor.GetColor32());
fDrawState.SetLowColor(fTabColor); fDrawingEngine->SetLowColor(fTabColor.GetColor32());
fDrawingEngine->SetFont(fDrawState.Font());
// figure out position of text // figure out position of text
font_height fontHeight; font_height fontHeight;
@@ -987,7 +989,8 @@ DefaultDecorator::_DrawTitle(BRect r)
: fTabRect.bottom - fTextOffset; : fTabRect.bottom - fTextOffset;
} }
fDrawingEngine->DrawString(fTruncatedTitle.String(), fTruncatedTitleLength, titlePos, &fDrawState); fDrawingEngine->DrawString(fTruncatedTitle.String(), fTruncatedTitleLength,
titlePos);
} }
// _DrawZoom // _DrawZoom
@@ -200,8 +200,6 @@ string_for_message_code(uint32 code, BString& string)
case AS_FILL_TRIANGLE: string = "AS_FILL_TRIANGLE"; break; case AS_FILL_TRIANGLE: string = "AS_FILL_TRIANGLE"; break;
case AS_DRAW_STRING: string = "AS_DRAW_STRING"; break; case AS_DRAW_STRING: string = "AS_DRAW_STRING"; break;
case AS_SET_FONT: string = "AS_SET_FONT"; break;
case AS_SET_FONT_SIZE: string = "AS_SET_FONT_SIZE"; break;
case AS_SYNC: string = "AS_SYNC"; break; case AS_SYNC: string = "AS_SYNC"; break;
+4
View File
@@ -53,6 +53,10 @@ class RGBColor {
bool operator==(const RGBColor& color) const; bool operator==(const RGBColor& color) const;
bool operator!=(const rgb_color& color) const; bool operator!=(const rgb_color& color) const;
bool operator!=(const RGBColor& color) const; bool operator!=(const RGBColor& color) const;
// conversion to rgb_color
operator rgb_color() const
{ return fColor32; }
bool IsTransparentMagic() const; bool IsTransparentMagic() const;
+10 -8
View File
@@ -1401,7 +1401,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
int32 lengthArray[numStrings]; int32 lengthArray[numStrings];
char *stringArray[numStrings]; char *stringArray[numStrings];
for (int32 i = 0; i < numStrings; i++) { for (int32 i = 0; i < numStrings; i++) {
// This version of ReadString allocates the strings, we free them below // This version of ReadString allocates the strings, we free
// them below
link.ReadString(&stringArray[i], (size_t *)&lengthArray[i]); link.ReadString(&stringArray[i], (size_t *)&lengthArray[i]);
} }
@@ -1415,13 +1416,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
if (!stringArray[i] || lengthArray[i] <= 0) if (!stringArray[i] || lengthArray[i] <= 0)
widthArray[i] = 0.0; widthArray[i] = 0.0;
else { else {
widthArray[i] = fDesktop->GetDrawingEngine()->StringWidth(stringArray[i], lengthArray[i], font); widthArray[i] = fDesktop->GetDrawingEngine()->
// NOTE: The line below will return the exact same thing. However, StringWidth(stringArray[i], lengthArray[i], font);
// the line above uses the AGG rendering backend, for which glyph caching // NOTE: The line below will return the exact same thing.
// actually works. It is about 20 times faster! // However, the line above uses the AGG rendering backend,
// TODO: I've disabled the AGG version for now, as it produces a dead lock // for which glyph caching actually works. It is about
// (font use), that I am currently too lazy to investigate... // 20 times faster!
// widthArray[i] = font.StringWidth(stringArray[i], lengthArray[i]); // widthArray[i] = font.StringWidth(stringArray[i],
// lengthArray[i]);
} }
} }
+3 -1
View File
@@ -339,6 +339,7 @@ ServerFont::GetTransformedFace(bool rotate, bool shear) const
FT_Set_Transform(face, &smatrix, NULL); FT_Set_Transform(face, &smatrix, NULL);
} }
// fStyle will be unlocked in PutTransformedFace()
return face; return face;
} }
@@ -433,7 +434,8 @@ ServerFont::GetEdges(const char charArray[], int32 numChars,
status_t status_t
ServerFont::GetEscapements(const char charArray[], int32 numChars, ServerFont::GetEscapements(const char charArray[], int32 numChars,
escapement_delta delta, BPoint escapementArray[], BPoint offsetArray[]) const escapement_delta delta, BPoint escapementArray[],
BPoint offsetArray[]) const
{ {
if (!charArray || numChars <= 0 || !escapementArray) if (!charArray || numChars <= 0 || !escapementArray)
return B_BAD_DATA; return B_BAD_DATA;
+47 -25
View File
@@ -131,7 +131,7 @@ ShapePainter::Draw(ViewLayer *view, BRect frame, bool filled)
} }
view->Window()->GetDrawingEngine()->DrawShape(frame, opCount, opList, ptCount, ptList, view->Window()->GetDrawingEngine()->DrawShape(frame, opCount, opList, ptCount, ptList,
view->CurrentState(), filled); filled);
} }
} }
@@ -182,7 +182,7 @@ stroke_line(ViewLayer *view, BPoint start, BPoint end)
{ {
view->ConvertToScreenForDrawing(&start); view->ConvertToScreenForDrawing(&start);
view->ConvertToScreenForDrawing(&end); view->ConvertToScreenForDrawing(&end);
view->Window()->GetDrawingEngine()->StrokeLine(start, end, view->CurrentState()); view->Window()->GetDrawingEngine()->StrokeLine(start, end);
} }
@@ -190,7 +190,7 @@ static void
stroke_rect(ViewLayer *view, BRect rect) stroke_rect(ViewLayer *view, BRect rect)
{ {
view->ConvertToScreenForDrawing(&rect); view->ConvertToScreenForDrawing(&rect);
view->Window()->GetDrawingEngine()->StrokeRect(rect, view->CurrentState()); view->Window()->GetDrawingEngine()->StrokeRect(rect);
} }
@@ -198,7 +198,7 @@ static void
fill_rect(ViewLayer *view, BRect rect) fill_rect(ViewLayer *view, BRect rect)
{ {
view->ConvertToScreenForDrawing(&rect); view->ConvertToScreenForDrawing(&rect);
view->Window()->GetDrawingEngine()->FillRect(rect, view->CurrentState()); view->Window()->GetDrawingEngine()->FillRect(rect);
} }
@@ -206,7 +206,8 @@ static void
stroke_round_rect(ViewLayer *view, BRect rect, BPoint radii) stroke_round_rect(ViewLayer *view, BRect rect, BPoint radii)
{ {
view->ConvertToScreenForDrawing(&rect); view->ConvertToScreenForDrawing(&rect);
view->Window()->GetDrawingEngine()->DrawRoundRect(rect, radii.x, radii.y, view->CurrentState(), false); view->Window()->GetDrawingEngine()->DrawRoundRect(rect, radii.x, radii.y,
false);
} }
@@ -214,7 +215,8 @@ static void
fill_round_rect(ViewLayer *view, BRect rect, BPoint radii) fill_round_rect(ViewLayer *view, BRect rect, BPoint radii)
{ {
view->ConvertToScreenForDrawing(&rect); view->ConvertToScreenForDrawing(&rect);
view->Window()->GetDrawingEngine()->DrawRoundRect(rect, radii.x, radii.y, view->CurrentState(), true); view->Window()->GetDrawingEngine()->DrawRoundRect(rect, radii.x, radii.y,
true);
} }
@@ -224,7 +226,7 @@ stroke_bezier(ViewLayer *view, const BPoint *viewPoints)
BPoint points[4]; BPoint points[4];
view->ConvertToScreenForDrawing(points, viewPoints, 4); view->ConvertToScreenForDrawing(points, viewPoints, 4);
view->Window()->GetDrawingEngine()->DrawBezier(points, view->CurrentState(), false); view->Window()->GetDrawingEngine()->DrawBezier(points, false);
} }
@@ -234,7 +236,7 @@ fill_bezier(ViewLayer *view, const BPoint *viewPoints)
BPoint points[4]; BPoint points[4];
view->ConvertToScreenForDrawing(points, viewPoints, 4); view->ConvertToScreenForDrawing(points, viewPoints, 4);
view->Window()->GetDrawingEngine()->DrawBezier(points, view->CurrentState(), true); view->Window()->GetDrawingEngine()->DrawBezier(points, true);
} }
@@ -245,7 +247,7 @@ stroke_arc(ViewLayer *view, BPoint center, BPoint radii, float startTheta,
BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x, BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x,
center.y + radii.y); center.y + radii.y);
view->ConvertToScreenForDrawing(&rect); view->ConvertToScreenForDrawing(&rect);
view->Window()->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, view->CurrentState(), false); view->Window()->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, false);
} }
@@ -256,7 +258,7 @@ fill_arc(ViewLayer *view, BPoint center, BPoint radii, float startTheta,
BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x, BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x,
center.y + radii.y); center.y + radii.y);
view->ConvertToScreenForDrawing(&rect); view->ConvertToScreenForDrawing(&rect);
view->Window()->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, view->CurrentState(), true); view->Window()->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, true);
} }
@@ -266,7 +268,7 @@ stroke_ellipse(ViewLayer *view, BPoint center, BPoint radii)
BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x, BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x,
center.y + radii.y); center.y + radii.y);
view->ConvertToScreenForDrawing(&rect); view->ConvertToScreenForDrawing(&rect);
view->Window()->GetDrawingEngine()->DrawEllipse(rect, view->CurrentState(), false); view->Window()->GetDrawingEngine()->DrawEllipse(rect, false);
} }
@@ -276,7 +278,7 @@ fill_ellipse(ViewLayer *view, BPoint center, BPoint radii)
BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x, BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x,
center.y + radii.y); center.y + radii.y);
view->ConvertToScreenForDrawing(&rect); view->ConvertToScreenForDrawing(&rect);
view->Window()->GetDrawingEngine()->DrawEllipse(rect, view->CurrentState(), true); view->Window()->GetDrawingEngine()->DrawEllipse(rect, true);
} }
@@ -295,9 +297,8 @@ stroke_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints, bool
BRect polyFrame; BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame); get_polygon_frame(points, numPoints, &polyFrame);
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
view->CurrentState(), false, false, isClosed && numPoints > 2);
isClosed && numPoints > 2);
} else { } else {
// avoid constructor/destructor calls by using malloc instead of new [] // avoid constructor/destructor calls by using malloc instead of new []
BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint)); BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint));
@@ -310,8 +311,7 @@ stroke_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints, bool
get_polygon_frame(points, numPoints, &polyFrame); get_polygon_frame(points, numPoints, &polyFrame);
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
view->CurrentState(), false, false, isClosed && numPoints > 2);
isClosed && numPoints > 2);
free(points); free(points);
} }
} }
@@ -333,7 +333,7 @@ fill_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints)
get_polygon_frame(points, numPoints, &polyFrame); get_polygon_frame(points, numPoints, &polyFrame);
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
view->CurrentState(), true, true); true, true);
} else { } else {
// avoid constructor/destructor calls by using malloc instead of new [] // avoid constructor/destructor calls by using malloc instead of new []
BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint)); BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint));
@@ -346,7 +346,7 @@ fill_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints)
get_polygon_frame(points, numPoints, &polyFrame); get_polygon_frame(points, numPoints, &polyFrame);
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
view->CurrentState(), true, true); true, true);
free(points); free(points);
} }
} }
@@ -373,13 +373,14 @@ fill_shape(ViewLayer *view, const BShape *shape)
static void static void
draw_string(ViewLayer *view, const char *string, float deltaSpace, float deltaNonSpace) draw_string(ViewLayer *view, const char *string, float deltaSpace,
float deltaNonSpace)
{ {
BPoint location = view->CurrentState()->PenLocation(); BPoint location = view->CurrentState()->PenLocation();
escapement_delta delta = {deltaSpace, deltaNonSpace }; escapement_delta delta = {deltaSpace, deltaNonSpace };
view->ConvertToScreenForDrawing(&location); view->ConvertToScreenForDrawing(&location);
view->Window()->GetDrawingEngine()->DrawString(string, strlen(string), location, view->Window()->GetDrawingEngine()->DrawString(string, strlen(string),
view->CurrentState(), &delta); location, &delta);
// TODO: Update pen location ? // TODO: Update pen location ?
} }
@@ -399,7 +400,7 @@ draw_pixels(ViewLayer *view, BRect src, BRect dest, int32 width, int32 height,
view->ConvertToScreenForDrawing(&dest); view->ConvertToScreenForDrawing(&dest);
view->Window()->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest, view->CurrentState()); view->Window()->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest);
} }
@@ -434,6 +435,11 @@ static void
pop_state(ViewLayer *view) pop_state(ViewLayer *view)
{ {
view->PopState(); view->PopState();
IntPoint p = view->ScrollingOffset();
p += IntPoint(view->CurrentState()->Origin());
view->Window()->GetDrawingEngine()->SetDrawState(
view->CurrentState(), p.x, p.y);
} }
@@ -476,6 +482,12 @@ static void
set_pen_location(ViewLayer *view, BPoint pt) set_pen_location(ViewLayer *view, BPoint pt)
{ {
view->CurrentState()->SetPenLocation(pt); view->CurrentState()->SetPenLocation(pt);
// TODO: faster version
IntPoint p = view->ScrollingOffset();
p += IntPoint(view->CurrentState()->Origin());
view->Window()->GetDrawingEngine()->SetDrawState(
view->CurrentState(), p.x, p.y);
} }
@@ -483,6 +495,7 @@ static void
set_drawing_mode(ViewLayer *view, drawing_mode mode) set_drawing_mode(ViewLayer *view, drawing_mode mode)
{ {
view->CurrentState()->SetDrawingMode(mode); view->CurrentState()->SetDrawingMode(mode);
view->Window()->GetDrawingEngine()->SetDrawingMode(mode);
} }
@@ -493,6 +506,7 @@ set_line_mode(ViewLayer *view, cap_mode capMode, join_mode joinMode, float miter
state->SetLineCapMode(capMode); state->SetLineCapMode(capMode);
state->SetLineJoinMode(joinMode); state->SetLineJoinMode(joinMode);
state->SetMiterLimit(miterLimit); state->SetMiterLimit(miterLimit);
view->Window()->GetDrawingEngine()->SetStrokeMode(capMode, joinMode, miterLimit);
} }
@@ -500,6 +514,7 @@ static void
set_pen_size(ViewLayer *view, float size) set_pen_size(ViewLayer *view, float size)
{ {
view->CurrentState()->SetPenSize(size); view->CurrentState()->SetPenSize(size);
view->Window()->GetDrawingEngine()->SetPenSize(size);
} }
@@ -507,6 +522,7 @@ static void
set_fore_color(ViewLayer *view, rgb_color color) set_fore_color(ViewLayer *view, rgb_color color)
{ {
view->CurrentState()->SetHighColor(RGBColor(color)); view->CurrentState()->SetHighColor(RGBColor(color));
view->Window()->GetDrawingEngine()->SetHighColor(color);
} }
@@ -514,13 +530,15 @@ static void
set_back_color(ViewLayer *view, rgb_color color) set_back_color(ViewLayer *view, rgb_color color)
{ {
view->CurrentState()->SetLowColor(RGBColor(color)); view->CurrentState()->SetLowColor(RGBColor(color));
view->Window()->GetDrawingEngine()->SetLowColor(color);
} }
static void static void
set_stipple_pattern(ViewLayer *view, pattern p) set_stipple_pattern(ViewLayer *view, pattern p)
{ {
printf("SetStipplePattern\n"); view->CurrentState()->SetPattern(Pattern(p));
view->Window()->GetDrawingEngine()->SetPattern(p);
} }
@@ -558,13 +576,17 @@ set_font_size(ViewLayer *view, float size)
ServerFont font; ServerFont font;
font.SetSize(size); font.SetSize(size);
view->CurrentState()->SetFont(font, B_FONT_SIZE); view->CurrentState()->SetFont(font, B_FONT_SIZE);
view->Window()->GetDrawingEngine()->SetFont(view->CurrentState()->Font());
} }
static void static void
set_font_rotate(ViewLayer *view, float rotation) set_font_rotate(ViewLayer *view, float rotation)
{ {
printf("SetFontRotate(%.2f)\n", rotation); ServerFont font;
font.SetRotation(rotation);
view->CurrentState()->SetFont(font, B_FONT_ROTATION);
view->Window()->GetDrawingEngine()->SetFont(view->CurrentState()->Font());
} }
+48 -49
View File
@@ -1034,6 +1034,16 @@ fDesktop->LockSingleWindow();
// at the fRedrawRequested member variable in _MessageLooper(). // at the fRedrawRequested member variable in _MessageLooper().
break; break;
case AS_SYNC:
// the synchronisation works by the fact that the client
// window is waiting for this reply, after having received it,
// client and server queues are in sync (earlier, the client
// may have pushed drawing commands at the server and now it
// knows they have all been carried out)
fLink.StartMessage(B_OK);
fLink.Flush();
break;
case AS_BEGIN_UPDATE: case AS_BEGIN_UPDATE:
DTRACE(("ServerWindowo %s: AS_BEGIN_UPDATE\n", Title())); DTRACE(("ServerWindowo %s: AS_BEGIN_UPDATE\n", Title()));
fWindowLayer->BeginUpdate(fLink); fWindowLayer->BeginUpdate(fLink);
@@ -1161,7 +1171,15 @@ fDesktop->LockSingleWindow();
// and take appropriate actions, then checking for fCurrentLayer->CurrentState() // and take appropriate actions, then checking for fCurrentLayer->CurrentState()
// is unnecessary // is unnecessary
if (fCurrentLayer == NULL || fCurrentLayer->CurrentState() == NULL) { if (fCurrentLayer == NULL || fCurrentLayer->CurrentState() == NULL) {
printf("ServerWindow %s received unexpected code - message offset %ld before top_view attached.\n", Title(), code - B_OK); BString codeName;
string_for_message_code(code, codeName);
printf("ServerWindow %s received unexpected code - "
"message '%s' before top_view attached.\n",
Title(), codeName.String());
if (link.NeedsReply()) {
fLink.StartMessage(B_ERROR);
fLink.Flush();
}
return; return;
} }
@@ -1231,8 +1249,10 @@ ServerWindow::_DispatchViewMessage(int32 code,
fDesktop->EventDispatcher().RemoveListener(EventTarget(), fDesktop->EventDispatcher().RemoveListener(EventTarget(),
token); token);
} }
if (fCurrentLayer == view)
_SetCurrentLayer(parent);
delete view; delete view;
} } // else we don't delete the root view
} }
break; break;
} }
@@ -1251,7 +1271,9 @@ ServerWindow::_DispatchViewMessage(int32 code,
{ {
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_FONT_STATE: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name())); DTRACE(("ServerWindow %s: Message AS_LAYER_SET_FONT_STATE: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
fCurrentLayer->CurrentState()->ReadFontFromLink(link); fCurrentLayer->CurrentState()->ReadFontFromLink(link);
_UpdateDrawState(fCurrentLayer); // _UpdateDrawState(fCurrentLayer);
fWindowLayer->GetDrawingEngine()->SetFont(
fCurrentLayer->CurrentState()->Font());
break; break;
} }
case AS_LAYER_GET_STATE: case AS_LAYER_GET_STATE:
@@ -1466,7 +1488,9 @@ ServerWindow::_DispatchViewMessage(int32 code,
fCurrentLayer->CurrentState()->SetLineJoinMode((join_mode)lineJoin); fCurrentLayer->CurrentState()->SetLineJoinMode((join_mode)lineJoin);
fCurrentLayer->CurrentState()->SetMiterLimit(miterLimit); fCurrentLayer->CurrentState()->SetMiterLimit(miterLimit);
_UpdateDrawState(fCurrentLayer); fWindowLayer->GetDrawingEngine()->SetStrokeMode((cap_mode)lineCap,
(join_mode)lineJoin, miterLimit);
// _UpdateDrawState(fCurrentLayer);
break; break;
} }
@@ -1606,8 +1630,10 @@ ServerWindow::_DispatchViewMessage(int32 code,
link.Read<int8>(&alphaFunc); link.Read<int8>(&alphaFunc);
fCurrentLayer->CurrentState()->SetBlendingMode((source_alpha)srcAlpha, fCurrentLayer->CurrentState()->SetBlendingMode((source_alpha)srcAlpha,
(alpha_function)alphaFunc); (alpha_function)alphaFunc);
_UpdateDrawState(fCurrentLayer); //_UpdateDrawState(fCurrentLayer);
fWindowLayer->GetDrawingEngine()->SetBlendingMode((source_alpha)srcAlpha,
(alpha_function)alphaFunc);
break; break;
} }
case AS_LAYER_GET_BLENDING_MODE: case AS_LAYER_GET_BLENDING_MODE:
@@ -1856,30 +1882,6 @@ ServerWindow::_DispatchViewMessage(int32 code,
fWindowLayer->GetDrawingEngine()->SetPattern(pat); fWindowLayer->GetDrawingEngine()->SetPattern(pat);
break; break;
} }
case AS_SET_FONT:
{
DTRACE(("ServerWindow %s: Message AS_SET_FONT\n", Title()));
// TODO: Implement AS_SET_FONT?
// Confusing!! But it works already!
break;
}
case AS_SET_FONT_SIZE:
{
DTRACE(("ServerWindow %s: Message AS_SET_FONT_SIZE\n", Title()));
// TODO: Implement AS_SET_FONT_SIZE?
break;
}
case AS_SYNC:
{
// the synchronisation works by the fact that the client
// window is waiting for this reply, after having received it,
// client and server queues are in sync (earlier, the client
// may have pushed drawing commands at the server and now it
// knows they have all been carried out)
fLink.StartMessage(B_OK);
fLink.Flush();
break;
}
case AS_LAYER_DRAG_IMAGE: case AS_LAYER_DRAG_IMAGE:
{ {
// TODO: flesh out AS_LAYER_DRAG_IMAGE // TODO: flesh out AS_LAYER_DRAG_IMAGE
@@ -2052,7 +2054,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
BPoint penPos = p2; BPoint penPos = p2;
fCurrentLayer->ConvertToScreenForDrawing(&p1); fCurrentLayer->ConvertToScreenForDrawing(&p1);
fCurrentLayer->ConvertToScreenForDrawing(&p2); fCurrentLayer->ConvertToScreenForDrawing(&p2);
drawingEngine->StrokeLine(p1, p2, fCurrentLayer->CurrentState()); drawingEngine->StrokeLine(p1, p2);
// We update the pen here because many DrawingEngine calls which do not update the // We update the pen here because many DrawingEngine calls which do not update the
// pen position actually call StrokeLine // pen position actually call StrokeLine
@@ -2086,7 +2088,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
BRect rect(left,top,right,bottom); BRect rect(left,top,right,bottom);
fCurrentLayer->ConvertToScreenForDrawing(&rect); fCurrentLayer->ConvertToScreenForDrawing(&rect);
drawingEngine->StrokeRect(rect, fCurrentLayer->CurrentState()); drawingEngine->StrokeRect(rect);
break; break;
} }
case AS_FILL_RECT: case AS_FILL_RECT:
@@ -2097,7 +2099,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
link.Read<BRect>(&rect); link.Read<BRect>(&rect);
fCurrentLayer->ConvertToScreenForDrawing(&rect); fCurrentLayer->ConvertToScreenForDrawing(&rect);
drawingEngine->FillRect(rect, fCurrentLayer->CurrentState()); drawingEngine->FillRect(rect);
break; break;
} }
case AS_LAYER_DRAW_BITMAP: case AS_LAYER_DRAW_BITMAP:
@@ -2114,7 +2116,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
if (bitmap) { if (bitmap) {
fCurrentLayer->ConvertToScreenForDrawing(&dstRect); fCurrentLayer->ConvertToScreenForDrawing(&dstRect);
drawingEngine->DrawBitmap(bitmap, srcRect, dstRect, fCurrentLayer->CurrentState()); drawingEngine->DrawBitmap(bitmap, srcRect, dstRect);
} }
break; break;
@@ -2132,8 +2134,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
link.Read<float>(&span); link.Read<float>(&span);
fCurrentLayer->ConvertToScreenForDrawing(&r); fCurrentLayer->ConvertToScreenForDrawing(&r);
drawingEngine->DrawArc(r, angle, span, fCurrentLayer->CurrentState(), drawingEngine->DrawArc(r, angle, span, code == AS_FILL_ARC);
code == AS_FILL_ARC);
break; break;
} }
case AS_STROKE_BEZIER: case AS_STROKE_BEZIER:
@@ -2147,8 +2148,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
fCurrentLayer->ConvertToScreenForDrawing(&pts[i]); fCurrentLayer->ConvertToScreenForDrawing(&pts[i]);
} }
drawingEngine->DrawBezier(pts, fCurrentLayer->CurrentState(), drawingEngine->DrawBezier(pts, code == AS_FILL_BEZIER);
code == AS_FILL_BEZIER);
break; break;
} }
case AS_STROKE_ELLIPSE: case AS_STROKE_ELLIPSE:
@@ -2160,7 +2160,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
link.Read<BRect>(&rect); link.Read<BRect>(&rect);
fCurrentLayer->ConvertToScreenForDrawing(&rect); fCurrentLayer->ConvertToScreenForDrawing(&rect);
drawingEngine->DrawEllipse(rect, fCurrentLayer->CurrentState(), code == AS_FILL_ELLIPSE); drawingEngine->DrawEllipse(rect, code == AS_FILL_ELLIPSE);
break; break;
} }
case AS_STROKE_ROUNDRECT: case AS_STROKE_ROUNDRECT:
@@ -2175,7 +2175,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
link.Read<float>(&yrad); link.Read<float>(&yrad);
fCurrentLayer->ConvertToScreenForDrawing(&rect); fCurrentLayer->ConvertToScreenForDrawing(&rect);
drawingEngine->DrawRoundRect(rect, xrad, yrad, fCurrentLayer->CurrentState(), code == AS_FILL_ROUNDRECT); drawingEngine->DrawRoundRect(rect, xrad, yrad, code == AS_FILL_ROUNDRECT);
break; break;
} }
case AS_STROKE_TRIANGLE: case AS_STROKE_TRIANGLE:
@@ -2194,7 +2194,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
link.Read<BRect>(&rect); link.Read<BRect>(&rect);
fCurrentLayer->ConvertToScreenForDrawing(&rect); fCurrentLayer->ConvertToScreenForDrawing(&rect);
drawingEngine->DrawTriangle(pts, rect, fCurrentLayer->CurrentState(), code == AS_FILL_TRIANGLE); drawingEngine->DrawTriangle(pts, rect, code == AS_FILL_TRIANGLE);
break; break;
} }
case AS_STROKE_POLYGON: case AS_STROKE_POLYGON:
@@ -2218,8 +2218,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
fCurrentLayer->ConvertToScreenForDrawing(&polyFrame); fCurrentLayer->ConvertToScreenForDrawing(&polyFrame);
drawingEngine->DrawPolygon(pointList, pointCount, polyFrame, drawingEngine->DrawPolygon(pointList, pointCount, polyFrame,
fCurrentLayer->CurrentState(), code == AS_FILL_POLYGON, code == AS_FILL_POLYGON, isClosed && pointCount > 2);
isClosed && pointCount > 2);
} }
delete[] pointList; delete[] pointList;
break; break;
@@ -2246,7 +2245,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
fCurrentLayer->ConvertToScreenForDrawing(&ptList[i]); fCurrentLayer->ConvertToScreenForDrawing(&ptList[i]);
drawingEngine->DrawShape(shapeFrame, opCount, opList, ptCount, ptList, drawingEngine->DrawShape(shapeFrame, opCount, opList, ptCount, ptList,
fCurrentLayer->CurrentState(), code == AS_FILL_SHAPE); code == AS_FILL_SHAPE);
} }
delete[] opList; delete[] opList;
@@ -2262,7 +2261,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
break; break;
fCurrentLayer->ConvertToScreenForDrawing(&region); fCurrentLayer->ConvertToScreenForDrawing(&region);
drawingEngine->FillRegion(region, fCurrentLayer->CurrentState()); drawingEngine->FillRegion(region);
break; break;
} }
@@ -2292,8 +2291,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
fCurrentLayer->ConvertToScreenForDrawing(&index->pt1); fCurrentLayer->ConvertToScreenForDrawing(&index->pt1);
fCurrentLayer->ConvertToScreenForDrawing(&index->pt2); fCurrentLayer->ConvertToScreenForDrawing(&index->pt2);
} }
drawingEngine->StrokeLineArray(lineCount, lineData, drawingEngine->StrokeLineArray(lineCount, lineData);
fCurrentLayer->CurrentState());
} }
break; break;
} }
@@ -2311,11 +2309,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
link.ReadString(&string); link.ReadString(&string);
fCurrentLayer->ConvertToScreenForDrawing(&location); fCurrentLayer->ConvertToScreenForDrawing(&location);
BPoint penLocation = drawingEngine->DrawString(string, length, location, BPoint penLocation = drawingEngine->DrawString(string, length,
fCurrentLayer->CurrentState(), &delta); location, &delta);
fCurrentLayer->ConvertFromScreenForDrawing(&penLocation); fCurrentLayer->ConvertFromScreenForDrawing(&penLocation);
fCurrentLayer->CurrentState()->SetPenLocation(penLocation); fCurrentLayer->CurrentState()->SetPenLocation(penLocation);
// pen location has changed, update DrawingEngine
// TODO: optimize with flags // TODO: optimize with flags
_UpdateDrawState(fCurrentLayer); _UpdateDrawState(fCurrentLayer);
+5 -7
View File
@@ -1212,16 +1212,14 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
if (rect.IsValid()/* && drawingEngine->Lock()*/) { if (rect.IsValid()/* && drawingEngine->Lock()*/) {
drawingEngine->ConstrainClippingRegion(redraw); drawingEngine->ConstrainClippingRegion(redraw);
DrawState defaultDrawState;
if (fBitmapOptions & B_TILE_BITMAP) { if (fBitmapOptions & B_TILE_BITMAP) {
// tile across entire view // tile across entire view
float start = rect.left; float start = rect.left;
while (rect.top < redraw->Frame().bottom) { while (rect.top < redraw->Frame().bottom) {
while (rect.left < redraw->Frame().right) { while (rect.left < redraw->Frame().right) {
drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, drawingEngine->DrawBitmap(fViewBitmap,
rect, &defaultDrawState); fBitmapSource, rect);
rect.OffsetBy(rect.Width() + 1, 0.0); rect.OffsetBy(rect.Width() + 1, 0.0);
} }
rect.OffsetBy(start - rect.left, rect.Height() + 1); rect.OffsetBy(start - rect.left, rect.Height() + 1);
@@ -1233,7 +1231,7 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
while (rect.left < redraw->Frame().right) { while (rect.left < redraw->Frame().right) {
drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource,
rect, &defaultDrawState); rect);
rect.OffsetBy(rect.Width() + 1, 0.0); rect.OffsetBy(rect.Width() + 1, 0.0);
} }
// remove horizontal stripe from clipping // remove horizontal stripe from clipping
@@ -1245,7 +1243,7 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
while (rect.top < redraw->Frame().bottom) { while (rect.top < redraw->Frame().bottom) {
drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource,
rect, &defaultDrawState); rect);
rect.OffsetBy(0.0, rect.Height() + 1); rect.OffsetBy(0.0, rect.Height() + 1);
} }
// remove vertical stripe from clipping // remove vertical stripe from clipping
@@ -1256,7 +1254,7 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
// no tiling at all // no tiling at all
drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource,
rect, &defaultDrawState); rect);
redraw->Exclude(rect); redraw->Exclude(rect);
} }
-1
View File
@@ -84,7 +84,6 @@ class WindowLayer {
ViewLayer* TopLayer() const { return fTopLayer; } ViewLayer* TopLayer() const { return fTopLayer; }
// TODO: only used for WorkspacesLayer, can go away if we do // TODO: only used for WorkspacesLayer, can go away if we do
// this differently one day // this differently one day
ViewLayer* ViewAt(const BPoint& where); ViewLayer* ViewAt(const BPoint& where);
virtual bool IsOffscreenWindow() const { return false; } virtual bool IsOffscreenWindow() const { return false; }
+72 -96
View File
@@ -13,6 +13,7 @@
#include <algo.h> #include <algo.h>
#include <stack.h> #include <stack.h>
#include "AGGTextRenderer.h"
#include "DrawState.h" #include "DrawState.h"
#include "Painter.h" #include "Painter.h"
#include "PNGDump.h" #include "PNGDump.h"
@@ -46,10 +47,10 @@ make_rect_valid(BRect& rect)
// extend_by_stroke_width // extend_by_stroke_width
static inline void static inline void
extend_by_stroke_width(BRect& rect, const DrawState* context) extend_by_stroke_width(BRect& rect, float penSize)
{ {
// "- 0.5" because if stroke width == 1, we don't need to extend // "- 0.5" because if stroke width == 1, we don't need to extend
float inset = -ceilf(context->PenSize() / 2.0 - 0.5); float inset = -ceilf(penSize / 2.0 - 0.5);
rect.InsetBy(inset, inset); rect.InsetBy(inset, inset);
} }
@@ -184,7 +185,7 @@ DrawingEngine::ConstrainClippingRegion(const BRegion* region)
void void
DrawingEngine::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset) DrawingEngine::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset)
{ {
fPainter->SetDrawState(state, false, xOffset, yOffset); fPainter->SetDrawState(state, true, xOffset, yOffset);
} }
@@ -209,11 +210,24 @@ DrawingEngine::SetPenSize(float size)
} }
void
DrawingEngine::SetStrokeMode(cap_mode lineCap, join_mode joinMode,
float miterLimit)
{
fPainter->SetStrokeMode(lineCap, joinMode, miterLimit);
}
void
DrawingEngine::SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc)
{
fPainter->SetBlendingMode(srcAlpha, alphaFunc);
}
void void
DrawingEngine::SetPattern(const struct pattern& pattern) DrawingEngine::SetPattern(const struct pattern& pattern)
{ {
// TODO: doing it like this prevents an optimization
// for font rendering (special "solid" drawing mode)
fPainter->SetPattern(pattern, false); fPainter->SetPattern(pattern, false);
} }
@@ -225,6 +239,13 @@ DrawingEngine::SetDrawingMode(drawing_mode mode)
} }
void
DrawingEngine::SetFont(const ServerFont& font)
{
fPainter->SetFont(font);
}
// #pragma mark - // #pragma mark -
@@ -505,8 +526,7 @@ DrawingEngine::InvertRect(BRect r)
// DrawBitmap // DrawBitmap
void void
DrawingEngine::DrawBitmap(ServerBitmap *bitmap, DrawingEngine::DrawBitmap(ServerBitmap *bitmap,
const BRect &source, const BRect &dest, const BRect &source, const BRect &dest)
const DrawState *d)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
@@ -514,7 +534,6 @@ DrawingEngine::DrawBitmap(ServerBitmap *bitmap,
if (clipped.IsValid()) { if (clipped.IsValid()) {
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
// fPainter->SetDrawState(d);
fPainter->DrawBitmap(bitmap, source, dest); fPainter->DrawBitmap(bitmap, source, dest);
fGraphicsCard->Invalidate(clipped); fGraphicsCard->Invalidate(clipped);
@@ -526,21 +545,18 @@ DrawingEngine::DrawBitmap(ServerBitmap *bitmap,
// DrawArc // DrawArc
void void
DrawingEngine::DrawArc(BRect r, const float &angle, DrawingEngine::DrawArc(BRect r, const float &angle,
const float &span, const DrawState *d, const float &span, bool filled)
bool filled)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
make_rect_valid(r); make_rect_valid(r);
BRect clipped(r); BRect clipped(r);
if (!filled) if (!filled)
extend_by_stroke_width(clipped, d); extend_by_stroke_width(clipped, fPainter->PenSize());
clipped = fPainter->ClipRect(r); clipped = fPainter->ClipRect(r);
if (clipped.IsValid()) { if (clipped.IsValid()) {
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
// fPainter->SetDrawState(d);
float xRadius = r.Width() / 2.0; float xRadius = r.Width() / 2.0;
float yRadius = r.Height() / 2.0; float yRadius = r.Height() / 2.0;
BPoint center(r.left + xRadius, BPoint center(r.left + xRadius,
@@ -559,14 +575,13 @@ DrawingEngine::DrawArc(BRect r, const float &angle,
// DrawBezier // DrawBezier
void void
DrawingEngine::DrawBezier(BPoint *pts, const DrawState *d, bool filled) DrawingEngine::DrawBezier(BPoint *pts, bool filled)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
// TODO: figure out bounds and hide cursor depending on that // TODO: figure out bounds and hide cursor depending on that
fGraphicsCard->HideSoftwareCursor(); fGraphicsCard->HideSoftwareCursor();
// fPainter->SetDrawState(d);
BRect touched = fPainter->DrawBezier(pts, filled); BRect touched = fPainter->DrawBezier(pts, filled);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
@@ -575,7 +590,7 @@ DrawingEngine::DrawBezier(BPoint *pts, const DrawState *d, bool filled)
// DrawEllipse // DrawEllipse
void void
DrawingEngine::DrawEllipse(BRect r, const DrawState *d, bool filled) DrawingEngine::DrawEllipse(BRect r, bool filled)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
@@ -584,7 +599,7 @@ DrawingEngine::DrawEllipse(BRect r, const DrawState *d, bool filled)
fPainter->AlignEllipseRect(&clipped, filled); fPainter->AlignEllipseRect(&clipped, filled);
if (!filled) if (!filled)
extend_by_stroke_width(clipped, d); extend_by_stroke_width(clipped, fPainter->PenSize());
clipped.left = floorf(clipped.left); clipped.left = floorf(clipped.left);
clipped.top = floorf(clipped.top); clipped.top = floorf(clipped.top);
@@ -596,7 +611,6 @@ DrawingEngine::DrawEllipse(BRect r, const DrawState *d, bool filled)
if (clipped.IsValid()) { if (clipped.IsValid()) {
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
// fPainter->SetDrawState(d);
fPainter->DrawEllipse(r, filled); fPainter->DrawEllipse(r, filled);
fGraphicsCard->Invalidate(clipped); fGraphicsCard->Invalidate(clipped);
@@ -608,19 +622,17 @@ DrawingEngine::DrawEllipse(BRect r, const DrawState *d, bool filled)
// DrawPolygon // DrawPolygon
void void
DrawingEngine::DrawPolygon(BPoint* ptlist, int32 numpts, DrawingEngine::DrawPolygon(BPoint* ptlist, int32 numpts,
BRect bounds, const DrawState* d, BRect bounds, bool filled, bool closed)
bool filled, bool closed)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
make_rect_valid(bounds); make_rect_valid(bounds);
if (!filled) if (!filled)
extend_by_stroke_width(bounds, d); extend_by_stroke_width(bounds, fPainter->PenSize());
bounds = fPainter->ClipRect(bounds); bounds = fPainter->ClipRect(bounds);
if (bounds.IsValid()) { if (bounds.IsValid()) {
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(bounds); bool cursorTouched = fGraphicsCard->HideSoftwareCursor(bounds);
// fPainter->SetDrawState(d);
fPainter->DrawPolygon(ptlist, numpts, filled, closed); fPainter->DrawPolygon(ptlist, numpts, filled, closed);
fGraphicsCard->Invalidate(bounds); fGraphicsCard->Invalidate(bounds);
@@ -756,20 +768,19 @@ DrawingEngine::FillRegion(BRegion& r, const RGBColor& color)
// #pragma mark - DrawState // #pragma mark - DrawState
void void
DrawingEngine::StrokeRect(BRect r, const DrawState *d) DrawingEngine::StrokeRect(BRect r)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
// support invalid rects // support invalid rects
make_rect_valid(r); make_rect_valid(r);
BRect clipped(r); BRect clipped(r);
extend_by_stroke_width(clipped, d); extend_by_stroke_width(clipped, fPainter->PenSize());
clipped = fPainter->ClipRect(clipped); clipped = fPainter->ClipRect(clipped);
if (clipped.IsValid()) { if (clipped.IsValid()) {
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
// fPainter->SetDrawState(d);
fPainter->StrokeRect(r); fPainter->StrokeRect(r);
fGraphicsCard->Invalidate(clipped); fGraphicsCard->Invalidate(clipped);
@@ -780,7 +791,7 @@ DrawingEngine::StrokeRect(BRect r, const DrawState *d)
void void
DrawingEngine::FillRect(BRect r, const DrawState *d) DrawingEngine::FillRect(BRect r)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
@@ -794,20 +805,20 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
// try hardware optimized version first // try hardware optimized version first
// if the rect is large enough // if the rect is large enough
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) { if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
if (d->GetPattern() == B_SOLID_HIGH if (fPainter->Pattern() == B_SOLID_HIGH
&& (d->GetDrawingMode() == B_OP_COPY && (fPainter->DrawingMode() == B_OP_COPY
|| d->GetDrawingMode() == B_OP_OVER)) { || fPainter->DrawingMode() == B_OP_OVER)) {
BRegion region(r); BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion()); region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->HighColor(), fGraphicsCard->FillRegion(region, fPainter->HighColor(),
fSuspendSyncLevel == 0 fSuspendSyncLevel == 0
|| cursorTouched); || cursorTouched);
doInSoftware = false; doInSoftware = false;
} else if (d->GetPattern() == B_SOLID_LOW } else if (fPainter->Pattern() == B_SOLID_LOW
&& d->GetDrawingMode() == B_OP_COPY) { && fPainter->DrawingMode() == B_OP_COPY) {
BRegion region(r); BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion()); region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->LowColor(), fGraphicsCard->FillRegion(region, fPainter->LowColor(),
fSuspendSyncLevel == 0 fSuspendSyncLevel == 0
|| cursorTouched); || cursorTouched);
doInSoftware = false; doInSoftware = false;
@@ -815,7 +826,6 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
} }
} }
if (doInSoftware) { if (doInSoftware) {
// fPainter->SetDrawState(d);
fPainter->FillRect(r); fPainter->FillRect(r);
fGraphicsCard->Invalidate(r); fGraphicsCard->Invalidate(r);
@@ -828,7 +838,7 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
void void
DrawingEngine::FillRegion(BRegion& r, const DrawState *d) DrawingEngine::FillRegion(BRegion& r)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
@@ -839,18 +849,18 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
bool doInSoftware = true; bool doInSoftware = true;
// try hardware optimized version first // try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) { if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
if (d->GetPattern() == B_SOLID_HIGH if (fPainter->Pattern() == B_SOLID_HIGH
&& (d->GetDrawingMode() == B_OP_COPY && (fPainter->DrawingMode() == B_OP_COPY
|| d->GetDrawingMode() == B_OP_OVER)) { || fPainter->DrawingMode() == B_OP_OVER)) {
r.IntersectWith(fPainter->ClippingRegion()); r.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(r, d->HighColor(), fGraphicsCard->FillRegion(r, fPainter->HighColor(),
fSuspendSyncLevel == 0 fSuspendSyncLevel == 0
|| cursorTouched); || cursorTouched);
doInSoftware = false; doInSoftware = false;
} else if (d->GetPattern() == B_SOLID_LOW } else if (fPainter->Pattern() == B_SOLID_LOW
&& d->GetDrawingMode() == B_OP_COPY) { && fPainter->DrawingMode() == B_OP_COPY) {
r.IntersectWith(fPainter->ClippingRegion()); r.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(r, d->LowColor(), fGraphicsCard->FillRegion(r, fPainter->LowColor(),
fSuspendSyncLevel == 0 fSuspendSyncLevel == 0
|| cursorTouched); || cursorTouched);
doInSoftware = false; doInSoftware = false;
@@ -858,7 +868,6 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
} }
if (doInSoftware) { if (doInSoftware) {
// fPainter->SetDrawState(d);
BRect touched = fPainter->FillRect(r.RectAt(0)); BRect touched = fPainter->FillRect(r.RectAt(0));
@@ -877,8 +886,7 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
void void
DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad, DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad, bool filled)
const DrawState* d, bool filled)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
@@ -895,7 +903,6 @@ DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad,
if (clipped.IsValid()) { if (clipped.IsValid()) {
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
// fPainter->SetDrawState(d);
BRect touched = filled ? fPainter->FillRoundRect(r, xrad, yrad) BRect touched = filled ? fPainter->FillRoundRect(r, xrad, yrad)
: fPainter->StrokeRoundRect(r, xrad, yrad); : fPainter->StrokeRoundRect(r, xrad, yrad);
@@ -908,8 +915,7 @@ DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad,
void void
DrawingEngine::DrawShape(const BRect& bounds, int32 opCount, DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
const uint32* opList, int32 ptCount, const BPoint* ptList, const uint32* opList, int32 ptCount, const BPoint* ptList, bool filled)
const DrawState* d, bool filled)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
@@ -917,7 +923,6 @@ DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
// shape is drawn on screen, TODO: optimize // shape is drawn on screen, TODO: optimize
fGraphicsCard->HideSoftwareCursor(); fGraphicsCard->HideSoftwareCursor();
// fPainter->SetDrawState(d);
BRect touched = fPainter->DrawShape(opCount, opList, BRect touched = fPainter->DrawShape(opCount, opList,
ptCount, ptList, ptCount, ptList,
filled); filled);
@@ -928,19 +933,17 @@ DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
void void
DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds, DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds, bool filled)
const DrawState* d, bool filled)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
BRect clipped(bounds); BRect clipped(bounds);
if (!filled) if (!filled)
extend_by_stroke_width(clipped, d); extend_by_stroke_width(clipped, fPainter->PenSize());
clipped = fPainter->ClipRect(clipped); clipped = fPainter->ClipRect(clipped);
if (clipped.IsValid()) { if (clipped.IsValid()) {
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped); bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
// fPainter->SetDrawState(d);
if (filled) if (filled)
fPainter->FillTriangle(pts[0], pts[1], pts[2]); fPainter->FillTriangle(pts[0], pts[1], pts[2]);
else else
@@ -954,18 +957,17 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds,
// StrokeLine // StrokeLine
void void
DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, DrawState* context) DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
BRect touched(start, end); BRect touched(start, end);
make_rect_valid(touched); make_rect_valid(touched);
extend_by_stroke_width(touched, context); extend_by_stroke_width(touched, fPainter->PenSize());
touched = fPainter->ClipRect(touched); touched = fPainter->ClipRect(touched);
if (touched.IsValid()) { if (touched.IsValid()) {
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched); bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched);
// fPainter->SetDrawState(context);
fPainter->StrokeLine(start, end); fPainter->StrokeLine(start, end);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
@@ -977,11 +979,11 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, DrawState* con
// StrokeLineArray // StrokeLineArray
void void
DrawingEngine::StrokeLineArray(int32 numLines, DrawingEngine::StrokeLineArray(int32 numLines,
const LineArrayData *linedata, const DrawState *d) const LineArrayData *linedata)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
if (!d || !linedata || numLines <= 0) if (!linedata || numLines <= 0)
return; return;
// figure out bounding box for line array // figure out bounding box for line array
@@ -999,13 +1001,14 @@ DrawingEngine::StrokeLineArray(int32 numLines,
max_c(data->pt1.y, data->pt2.y)); max_c(data->pt1.y, data->pt2.y));
touched = touched | box; touched = touched | box;
} }
extend_by_stroke_width(touched, d); extend_by_stroke_width(touched, fPainter->PenSize());
touched = fPainter->ClipRect(touched); touched = fPainter->ClipRect(touched);
if (touched.IsValid()) { if (touched.IsValid()) {
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched); bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched);
data = (const LineArrayData *)&(linedata[0]); data = (const LineArrayData *)&(linedata[0]);
rgb_color oldColor = fPainter->HighColor();
fPainter->SetHighColor(data->color); fPainter->SetHighColor(data->color);
fPainter->StrokeLine(data->pt1, data->pt2); fPainter->StrokeLine(data->pt1, data->pt2);
@@ -1016,7 +1019,7 @@ DrawingEngine::StrokeLineArray(int32 numLines,
} }
// restore correct drawing state highcolor // restore correct drawing state highcolor
fPainter->SetHighColor(d->HighColor()); fPainter->SetHighColor(oldColor);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
if (cursorTouched) if (cursorTouched)
@@ -1028,22 +1031,14 @@ DrawingEngine::StrokeLineArray(int32 numLines,
BPoint BPoint
DrawingEngine::DrawString(const char* string, int32 length, DrawingEngine::DrawString(const char* string, int32 length,
const BPoint& pt, DrawState* d, const BPoint& pt, escapement_delta* delta)
escapement_delta* delta)
{ {
CRASH_IF_NOT_LOCKED CRASH_IF_NOT_LOCKED
// TODO: use delta FontLocker locker(&fPainter->Font());
FontLocker locker(d);
BPoint penLocation = pt; BPoint penLocation = pt;
fPainter->SetDrawState(d, true);
// TODO: this will reset the scrolling offsets used for
// pattern drawing again, it is really necessary to change
// the whole graphics state synchronization between DrawState
// and Painter, and remove any individual SetDrawState() calls
// like here
//bigtime_t now = system_time(); //bigtime_t now = system_time();
// TODO: BoundingBox is quite slow!! Optimizing it will be beneficial. // TODO: BoundingBox is quite slow!! Optimizing it will be beneficial.
// Cursiously, the DrawString after it is actually faster!?! // Cursiously, the DrawString after it is actually faster!?!
@@ -1074,10 +1069,9 @@ DrawingEngine::DrawString(const char* string, int32 length,
// StringWidth // StringWidth
float float
DrawingEngine::StringWidth(const char* string, int32 length, DrawingEngine::StringWidth(const char* string, int32 length,
const DrawState* d, escapement_delta* delta) escapement_delta* delta)
{ {
// TODO: use delta FontLocker locker(&fPainter->Font());
FontLocker locker(d);
float width = 0.0; float width = 0.0;
// NOTE: For now it is enough to block on the // NOTE: For now it is enough to block on the
@@ -1086,7 +1080,7 @@ DrawingEngine::StringWidth(const char* string, int32 length,
// deadlock in case another thread holds the font // deadlock in case another thread holds the font
// lock already and then tries to lock the drawing // lock already and then tries to lock the drawing
// engine after it is already locked here (race condition) // engine after it is already locked here (race condition)
width = fPainter->StringWidth(string, length, d); width = fPainter->StringWidth(string, length, delta);
return width; return width;
} }
@@ -1095,30 +1089,12 @@ float
DrawingEngine::StringWidth(const char* string, int32 length, DrawingEngine::StringWidth(const char* string, int32 length,
const ServerFont& font, escapement_delta* delta) const ServerFont& font, escapement_delta* delta)
{ {
DrawState d; FontLocker locker(&font);
d.SetFont(font);
return StringWidth(string, length, &d, delta);
}
// StringHeight AGGTextRenderer* renderer = AGGTextRenderer::Default();
float renderer->SetFont(font);
DrawingEngine::StringHeight(const char *string, int32 length,
const DrawState *d)
{
FontLocker locker(d);
float height = 0.0; return renderer->StringWidth(string, length, delta);
// NOTE: For now it is enough to block on the
// font style lock, this already prevents multiple
// threads from executing this code and avoids a
// deadlock in case another thread holds the font
// lock already and then tries to lock the drawing
// engine after it is already locked here (race condition)
fPainter->SetDrawState(d, true);
BPoint dummy1(0.0, 0.0);
BPoint dummy2(0.0, 0.0);
height = fPainter->BoundingBox(string, length, dummy1, &dummy2).Height();
return height;
} }
// #pragma mark - // #pragma mark -
+23 -28
View File
@@ -72,8 +72,13 @@ public:
void SetHighColor(const rgb_color& color); void SetHighColor(const rgb_color& color);
void SetLowColor(const rgb_color& color); void SetLowColor(const rgb_color& color);
void SetPenSize(float size); void SetPenSize(float size);
void SetStrokeMode(cap_mode lineCap, join_mode joinMode,
float miterLimit);
void SetPattern(const struct pattern& pattern); void SetPattern(const struct pattern& pattern);
void SetDrawingMode(drawing_mode mode); void SetDrawingMode(drawing_mode mode);
void SetBlendingMode(source_alpha srcAlpha,
alpha_function alphaFunc);
void SetFont(const ServerFont& font);
void SuspendAutoSync(); void SuspendAutoSync();
void Sync(); void Sync();
@@ -85,24 +90,18 @@ public:
void InvertRect(BRect r); void InvertRect(BRect r);
void DrawBitmap(ServerBitmap *bitmap, void DrawBitmap(ServerBitmap *bitmap,
const BRect &source, const BRect &dest, const BRect &source, const BRect &dest);
const DrawState *d);
// drawing primitives // drawing primitives
void DrawArc(BRect r, const float &angle, void DrawArc(BRect r, const float &angle,
const float &span, const float &span, bool filled);
const DrawState *d,
bool filled);
void DrawBezier(BPoint *pts, const DrawState *d, void DrawBezier(BPoint *pts, bool filled);
bool filled);
void DrawEllipse(BRect r, const DrawState *d, void DrawEllipse(BRect r, bool filled);
bool filled);
void DrawPolygon(BPoint *ptlist, int32 numpts, void DrawPolygon(BPoint *ptlist, int32 numpts,
BRect bounds, const DrawState *d, BRect bounds, bool filled, bool closed);
bool filled, bool closed);
// these RGBColor versions are used internally by the server // these RGBColor versions are used internally by the server
void StrokePoint(const BPoint& pt, void StrokePoint(const BPoint& pt,
@@ -111,53 +110,49 @@ public:
void FillRect(BRect r, const RGBColor &color); void FillRect(BRect r, const RGBColor &color);
void FillRegion(BRegion& r, const RGBColor& color); void FillRegion(BRegion& r, const RGBColor& color);
void StrokeRect(BRect r, const DrawState *d); void StrokeRect(BRect r);
void FillRect(BRect r, const DrawState *d); void FillRect(BRect r);
void FillRegion(BRegion& r, const DrawState *d); void FillRegion(BRegion& r);
void DrawRoundRect(BRect r, float xrad, void DrawRoundRect(BRect r, float xrad,
float yrad, const DrawState *d, float yrad, bool filled);
bool filled);
void DrawShape(const BRect& bounds, void DrawShape(const BRect& bounds,
int32 opcount, const uint32* oplist, int32 opcount, const uint32* oplist,
int32 ptcount, const BPoint* ptlist, int32 ptcount, const BPoint* ptlist,
const DrawState* d, bool filled); bool filled);
void DrawTriangle(BPoint* pts, const BRect& bounds, void DrawTriangle(BPoint* pts, const BRect& bounds,
const DrawState* d, bool filled); bool filled);
// this version used by Decorator // this version used by Decorator
void StrokeLine(const BPoint& start, void StrokeLine(const BPoint& start,
const BPoint& end, const RGBColor& color); const BPoint& end, const RGBColor& color);
void StrokeLine(const BPoint& start, void StrokeLine(const BPoint& start,
const BPoint& end, DrawState* d); const BPoint& end);
void StrokeLineArray(int32 numlines, void StrokeLineArray(int32 numlines,
const LineArrayData* data, const LineArrayData* data);
const DrawState* d);
// -------- text related calls // -------- text related calls
// DrawState is NOT const because this call updates the // returns the pen position behind the (virtually) drawn
// pen position in the passed DrawState // string
BPoint DrawString(const char* string, int32 length, BPoint DrawString(const char* string, int32 length,
const BPoint& pt, DrawState* d, const BPoint& pt,
escapement_delta* delta = NULL); escapement_delta* delta = NULL);
float StringWidth(const char* string, int32 length, float StringWidth(const char* string, int32 length,
const DrawState* d,
escapement_delta* delta = NULL); escapement_delta* delta = NULL);
// convenience function which is independent of graphics
// state (to be used by Decorator or ServerApp etc)
float StringWidth(const char* string, float StringWidth(const char* string,
int32 length, const ServerFont& font, int32 length, const ServerFont& font,
escapement_delta* delta = NULL); escapement_delta* delta = NULL);
float StringHeight(const char* string,
int32 length, const DrawState* d);
private: private:
BRect _CopyRect(BRect r, int32 xOffset, BRect _CopyRect(BRect r, int32 xOffset,
int32 yOffset) const; int32 yOffset) const;
+49 -36
View File
@@ -47,6 +47,7 @@
#define CHECK_CLIPPING if (!fValidClipping) return BRect(0, 0, -1, -1); #define CHECK_CLIPPING if (!fValidClipping) return BRect(0, 0, -1, -1);
#define CHECK_CLIPPING_NO_RETURN if (!fValidClipping) return;
// constructor // constructor
@@ -82,12 +83,6 @@ Painter::Painter()
{ {
fPixelFormat.SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode, false); fPixelFormat.SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode, false);
// Usually, the drawing engine will lock the font for us when
// needed - unfortunately, it can't know we need it here
fFont.Lock();
_UpdateFont();
fFont.Unlock();
#if ALIASED_DRAWING #if ALIASED_DRAWING
fRasterizer.gamma(agg::gamma_threshold(0.5)); fRasterizer.gamma(agg::gamma_threshold(0.5));
#endif #endif
@@ -217,13 +212,32 @@ Painter::SetDrawingMode(drawing_mode mode)
} }
} }
// SetBlendingMode
void
Painter::SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc)
{
if (fAlphaSrcMode != srcAlpha || fAlphaFncMode != alphaFunc) {
fAlphaSrcMode = srcAlpha;
fAlphaFncMode = alphaFunc;
if (fDrawingMode == B_OP_ALPHA)
_UpdateDrawingMode();
}
}
// SetPenSize // SetPenSize
void void
Painter::SetPenSize(float size) Painter::SetPenSize(float size)
{ {
if (fPenSize != size) { fPenSize = size;
fPenSize = size; }
}
// SetStrokeMode
void
Painter::SetStrokeMode(cap_mode lineCap, join_mode joinMode, float miterLimit)
{
fLineCapMode = lineCap;
fLineJoinMode = joinMode;
fMiterLimit = miterLimit;
} }
// SetPattern // SetPattern
@@ -258,36 +272,21 @@ void
Painter::SetFont(const ServerFont& font) Painter::SetFont(const ServerFont& font)
{ {
fFont = font; fFont = font;
_UpdateFont();
} }
// #pragma mark - drawing // #pragma mark - drawing
// StrokeLine // StrokeLine
BRect void
Painter::StrokeLine(BPoint a, BPoint b) Painter::StrokeLine(BPoint a, BPoint b)
{ {
CHECK_CLIPPING CHECK_CLIPPING_NO_RETURN
// "false" means not to do the pixel center offset, // "false" means not to do the pixel center offset,
// because it would mess up our optimized versions // because it would mess up our optimized versions
_Transform(&a, false); _Transform(&a, false);
_Transform(&b, false); _Transform(&b, false);
BRect touched(min_c(a.x, b.x), min_c(a.y, b.y),
max_c(a.x, b.x), max_c(a.y, b.y));
// This is supposed to stop right here if we can see
// that we're definitaly outside the clipping reagion.
// Extending by penSize like that is not really correct,
// but fast and only triggers unnecessary calculation
// in a few edge cases
touched.InsetBy(-(fPenSize - 1), -(fPenSize - 1));
if (!touched.Intersects(fClippingRegion->Frame())) {
touched.Set(0.0, 0.0, -1.0, -1.0);
return touched;
}
// first, try an optimized version // first, try an optimized version
if (fPenSize == 1.0 if (fPenSize == 1.0
&& (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)) { && (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)) {
@@ -295,10 +294,8 @@ Painter::StrokeLine(BPoint a, BPoint b)
pattern pat = *fPatternHandler.GetR5Pattern(); pattern pat = *fPatternHandler.GetR5Pattern();
if (pat == B_SOLID_HIGH && if (pat == B_SOLID_HIGH &&
StraightLine(a, b, fPatternHandler.HighColor().GetColor32())) { StraightLine(a, b, fPatternHandler.HighColor().GetColor32())) {
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())) {
return _Clipped(touched);
} }
} }
@@ -317,7 +314,7 @@ Painter::StrokeLine(BPoint a, BPoint b)
fPath.line_to(a.x + 1, a.y + 1); fPath.line_to(a.x + 1, a.y + 1);
fPath.line_to(a.x, a.y + 1); fPath.line_to(a.x, a.y + 1);
touched = _FillPath(fPath); _FillPath(fPath);
} }
} else { } else {
// do the pixel center offset here // do the pixel center offset here
@@ -364,10 +361,8 @@ Painter::StrokeLine(BPoint a, BPoint b)
fPath.move_to(a.x, a.y); fPath.move_to(a.x, a.y);
fPath.line_to(b.x, b.y); fPath.line_to(b.x, b.y);
touched = _StrokePath(fPath); _StrokePath(fPath);
} }
return _Clipped(touched);
} }
// StraightLine // StraightLine
@@ -987,18 +982,27 @@ Painter::DrawString(const char* utf8String, uint32 length,
BRect bounds(0.0, 0.0, -1.0, -1.0); BRect bounds(0.0, 0.0, -1.0, -1.0);
// text is not rendered with patterns, but we need to
// make sure that the previous pattern is restored
pattern oldPattern = *fPatternHandler.GetR5Pattern();
SetPattern(B_SOLID_HIGH, true); SetPattern(B_SOLID_HIGH, true);
// make sure the text renderer is using our font (the global
// instance of the text renderer is used by everyone)
_UpdateFont();
bounds = fTextRenderer->RenderString(utf8String, bounds = fTextRenderer->RenderString(utf8String,
length, length,
&fRenderer, &fRenderer,
&fRendererBin, &fRendererBin,
fUnpackedScanline,
baseLine, baseLine,
fClippingRegion->Frame(), fClippingRegion->Frame(),
false, false,
&fPenLocation, &fPenLocation,
delta); delta);
SetPattern(oldPattern);
return _Clipped(bounds); return _Clipped(bounds);
} }
@@ -1013,21 +1017,30 @@ Painter::BoundingBox(const char* utf8String, uint32 length,
baseLine.y = roundf(baseLine.y); baseLine.y = roundf(baseLine.y);
} }
// make sure the text renderer is using our font (the global
// instance of the text renderer is used by everyone)
_UpdateFont();
static BRect dummy; static BRect dummy;
return fTextRenderer->RenderString(utf8String, return fTextRenderer->RenderString(utf8String,
length, length,
&fRenderer, &fRenderer,
&fRendererBin, &fRendererBin,
fUnpackedScanline,
baseLine, dummy, true, penLocation, baseLine, dummy, true, penLocation,
delta); delta);
} }
// StringWidth // StringWidth
float float
Painter::StringWidth(const char* utf8String, uint32 length, const DrawState* context) Painter::StringWidth(const char* utf8String, uint32 length,
const escapement_delta* delta)
{ {
SetFont(context->Font()); // make sure the text renderer is using our font (the global
return fTextRenderer->StringWidth(utf8String, length); // instance of the text renderer is used by everyone)
_UpdateFont();
return fTextRenderer->StringWidth(utf8String, length, delta);
} }
// #pragma mark - // #pragma mark -
@@ -1133,7 +1146,7 @@ Painter::_Clipped(const BRect& rect) const
// _UpdateFont // _UpdateFont
void void
Painter::_UpdateFont() Painter::_UpdateFont() const
{ {
fTextRenderer->SetFont(fFont); fTextRenderer->SetFont(fFont);
} }
+18 -4
View File
@@ -65,22 +65,36 @@ class Painter {
inline void SetLowColor(const RGBColor& color) inline void SetLowColor(const RGBColor& color)
{ SetLowColor(color.GetColor32()); } { SetLowColor(color.GetColor32()); }
inline rgb_color LowColor() const
{ return fPatternHandler.
LowColor().GetColor32(); }
void SetPenSize(float size); void SetPenSize(float size);
inline float PenSize() const
{ return fPenSize; }
void SetStrokeMode(cap_mode lineCap,
join_mode joinMode, float miterLimit);
void SetPattern(const pattern& p, void SetPattern(const pattern& p,
bool drawingText = false); bool drawingText = false);
inline pattern Pattern() const
{ return *fPatternHandler.GetR5Pattern(); }
void SetDrawingMode(drawing_mode mode); void SetDrawingMode(drawing_mode mode);
inline drawing_mode DrawingMode() const inline drawing_mode DrawingMode() const
{ return fDrawingMode; } { return fDrawingMode; }
void SetBlendingMode(source_alpha srcAlpha,
alpha_function alphaFunc);
void SetPenLocation(const BPoint& location); void SetPenLocation(const BPoint& location);
BPoint PenLocation() const inline BPoint PenLocation() const
{ return fPenLocation; } { return fPenLocation; }
void SetFont(const ServerFont& font); void SetFont(const ServerFont& font);
inline const ServerFont& Font() const
{ return fFont; }
// painting functions // painting functions
// lines // lines
BRect StrokeLine( BPoint a, void StrokeLine( BPoint a,
BPoint b); BPoint b);
// returns true if the line was either vertical or horizontal // returns true if the line was either vertical or horizontal
@@ -174,7 +188,7 @@ class Painter {
float StringWidth( const char* utf8String, float StringWidth( const char* utf8String,
uint32 length, uint32 length,
const DrawState* context); const escapement_delta* delta = NULL);
// bitmaps // bitmaps
@@ -197,7 +211,7 @@ class Painter {
bool centerOffset = true) const; bool centerOffset = true) const;
BRect _Clipped(const BRect& rect) const; BRect _Clipped(const BRect& rect) const;
void _UpdateFont(); void _UpdateFont() const;
void _UpdateLineWidth(); void _UpdateLineWidth();
void _UpdateDrawingMode(bool drawingText = false); void _UpdateDrawingMode(bool drawingText = false);
void _SetRendererColor(const rgb_color& color) const; void _SetRendererColor(const rgb_color& color) const;
@@ -166,6 +166,7 @@ AGGTextRenderer::RenderString(const char* string,
uint32 length, uint32 length,
renderer_type* solidRenderer, renderer_type* solidRenderer,
renderer_bin_type* binRenderer, renderer_bin_type* binRenderer,
scanline_unpacked_type& scanline,
const BPoint& baseLine, const BPoint& baseLine,
const BRect& clippingFrame, const BRect& clippingFrame,
bool dryRun, bool dryRun,
@@ -295,8 +296,6 @@ AGGTextRenderer::RenderString(const char* string,
case agg::glyph_data_outline: { case agg::glyph_data_outline: {
fRasterizer.reset(); fRasterizer.reset();
// TODO: this currently falls into an endless loop - this is a quick fix to keep the
// app_server running - instead of the characters, their bounding boxes will be shown
if (fContour.width() == 0.0) { if (fContour.width() == 0.0) {
fRasterizer.add_path(transformedOutline); fRasterizer.add_path(transformedOutline);
} else { } else {
@@ -314,7 +313,8 @@ AGGTextRenderer::RenderString(const char* string,
fRasterizer.add_path(ps); fRasterizer.add_path(ps);
#endif #endif
agg::render_scanlines(fRasterizer, fScanline, *solidRenderer); agg::render_scanlines(fRasterizer, scanline,
*solidRenderer);
break; break;
} }
default: default:
@@ -344,7 +344,8 @@ AGGTextRenderer::RenderString(const char* string,
double double
AGGTextRenderer::StringWidth(const char* string, uint32 length) AGGTextRenderer::StringWidth(const char* string, uint32 length,
const escapement_delta* delta)
{ {
// NOTE: The implementation does not take font rotation (or shear) // NOTE: The implementation does not take font rotation (or shear)
// into account. Just like on R5. Should it ever be desirable to // into account. Just like on R5. Should it ever be desirable to
@@ -370,6 +371,11 @@ AGGTextRenderer::StringWidth(const char* string, uint32 length)
if (!firstLoop && fKerning) if (!firstLoop && fKerning)
fFontCache.add_kerning(&width, &y); fFontCache.add_kerning(&width, &y);
width += glyph->advance_x; width += glyph->advance_x;
if (delta) {
width += is_white_space(charCode) ?
delta->space : delta->nonspace;
}
} }
firstLoop = false; firstLoop = false;
@@ -48,6 +48,7 @@ class AGGTextRenderer {
uint32 length, uint32 length,
renderer_type* solidRenderer, renderer_type* solidRenderer,
renderer_bin_type* binRenderer, renderer_bin_type* binRenderer,
scanline_unpacked_type& scanline,
const BPoint& baseLine, const BPoint& baseLine,
const BRect& clippingFrame, const BRect& clippingFrame,
bool dryRun = false, bool dryRun = false,
@@ -55,7 +56,8 @@ class AGGTextRenderer {
const escapement_delta* delta = NULL); const escapement_delta* delta = NULL);
double StringWidth(const char* utf8String, double StringWidth(const char* utf8String,
uint32 length); uint32 length,
const escapement_delta* delta = NULL);
private: private:
@@ -72,10 +74,10 @@ class AGGTextRenderer {
conv_font_curve_type fCurves; conv_font_curve_type fCurves;
conv_font_contour_type fContour; conv_font_contour_type fContour;
scanline_unpacked_type fScanline;
rasterizer_type fRasterizer; rasterizer_type fRasterizer;
// TODO: both of these are actually in Painter already // NOTE: the object has it's own rasterizer object
// and could be reused by this object // since it might be using a different gamma setting
// to support non-anti-aliased text rendering
char* fUnicodeBuffer; char* fUnicodeBuffer;
int32 fUnicodeBufferSize; int32 fUnicodeBufferSize;