app_server: extract coordinate conversion class

* Move coordinate conversion into a new class SimpleTransform. It
  supports scaling and translation which is sufficient for conversion
  between screen, local and pen (drawing) coordinates.

* Because all the overloaded methods for converting
  BPoint/BRect/BRegion/etc are now within the single SimpleTransform
  class, the interfaces of Canvas, View, DrawState, etc. are slimmed
  down. These classes have too many responsibilities, so some will be
  factored out into separate classes, this being the first.
This commit is contained in:
Julian Harnath
2015-07-25 16:31:19 +02:00
parent ab1bd2fd07
commit 6f2a446e2e
11 changed files with 462 additions and 582 deletions
+40 -165
View File
@@ -17,17 +17,22 @@
#include <new>
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <GradientRadialFocus.h>
#include <GradientDiamond.h>
#include <GradientConic.h>
#include <Region.h>
#include "DrawingEngine.h"
#include "DrawState.h"
#if __GNUC__ >= 3
# define GCC_2_NRV(x)
// GCC >= 3.1 doesn't need it anymore
#else
# define GCC_2_NRV(x) return x;
// GCC 2 named return value syntax
// see http://gcc.gnu.org/onlinedocs/gcc-2.95.2/gcc_5.html#SEC106
#endif
Canvas::Canvas()
:
fDrawState(new(std::nothrow) DrawState())
@@ -149,179 +154,49 @@ Canvas::GetAlphaMask() const
}
//! converts a point from local *drawing* to screen coordinate system
void
Canvas::ConvertToScreenForDrawing(BPoint* point) const
SimpleTransform
Canvas::LocalToScreenTransform() const GCC_2_NRV(transform)
{
fDrawState->Transform(point);
// NOTE: from here on, don't use the
// "*ForDrawing()" versions of the parent!
ConvertToScreen(point);
#if __GNUC__ >= 3
SimpleTransform transform;
#endif
_LocalToScreenTransform(transform);
return transform;
}
//! converts a rect from local *drawing* to screen coordinate system
void
Canvas::ConvertToScreenForDrawing(BRect* rect) const
SimpleTransform
Canvas::ScreenToLocalTransform() const GCC_2_NRV(transform)
{
fDrawState->Transform(rect);
// NOTE: from here on, don't use the
// "*ForDrawing()" versions of the parent!
ConvertToScreen(rect);
#if __GNUC__ >= 3
SimpleTransform transform;
#endif
_ScreenToLocalTransform(transform);
return transform;
}
//! converts a region from local *drawing* to screen coordinate system
void
Canvas::ConvertToScreenForDrawing(BRegion* region) const
SimpleTransform
Canvas::PenToScreenTransform() const GCC_2_NRV(transform)
{
fDrawState->Transform(region);
// NOTE: from here on, don't use the
// "*ForDrawing()" versions of the parent!
ConvertToScreen(region);
#if __GNUC__ >= 3
SimpleTransform transform;
#endif
fDrawState->Transform(transform);
_LocalToScreenTransform(transform);
return transform;
}
//! converts a gradient from local *drawing* to screen coordinate system
void
Canvas::ConvertToScreenForDrawing(BGradient* gradient) const
SimpleTransform
Canvas::ScreenToPenTransform() const GCC_2_NRV(transform)
{
switch (gradient->GetType()) {
case BGradient::TYPE_LINEAR:
{
BGradientLinear* linear = (BGradientLinear*) gradient;
BPoint start = linear->Start();
BPoint end = linear->End();
fDrawState->Transform(&start);
ConvertToScreen(&start);
fDrawState->Transform(&end);
ConvertToScreen(&end);
linear->SetStart(start);
linear->SetEnd(end);
break;
}
case BGradient::TYPE_RADIAL:
{
BGradientRadial* radial = (BGradientRadial*) gradient;
BPoint center = radial->Center();
fDrawState->Transform(&center);
ConvertToScreen(&center);
radial->SetCenter(center);
break;
}
case BGradient::TYPE_RADIAL_FOCUS:
{
BGradientRadialFocus* radialFocus = (BGradientRadialFocus*) gradient;
BPoint center = radialFocus->Center();
BPoint focal = radialFocus->Focal();
fDrawState->Transform(&center);
ConvertToScreen(&center);
fDrawState->Transform(&focal);
ConvertToScreen(&focal);
radialFocus->SetCenter(center);
radialFocus->SetFocal(focal);
break;
}
case BGradient::TYPE_DIAMOND:
{
BGradientDiamond* diamond = (BGradientDiamond*) gradient;
BPoint center = diamond->Center();
fDrawState->Transform(&center);
ConvertToScreen(&center);
diamond->SetCenter(center);
break;
}
case BGradient::TYPE_CONIC:
{
BGradientConic* conic = (BGradientConic*) gradient;
BPoint center = conic->Center();
fDrawState->Transform(&center);
ConvertToScreen(&center);
conic->SetCenter(center);
break;
}
case BGradient::TYPE_NONE:
{
break;
}
}
// Make sure the gradient is fully padded so that out of bounds access
// get the correct colors
gradient->SortColorStopsByOffset();
BGradient::ColorStop* end = gradient->ColorStopAtFast(
gradient->CountColorStops() - 1);
if (end->offset != 255)
gradient->AddColor(end->color, 255);
BGradient::ColorStop* start = gradient->ColorStopAtFast(0);
if (start->offset != 0)
gradient->AddColor(start->color, 0);
gradient->SortColorStopsByOffset();
}
//! converts points from local *drawing* to screen coordinate system
void
Canvas::ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const
{
// TODO: optimize this, it should be smarter
while (num--) {
*dst = *src;
fDrawState->Transform(dst);
// NOTE: from here on, don't use the
// "*ForDrawing()" versions of the parent!
ConvertToScreen(dst);
src++;
dst++;
}
}
//! converts rects from local *drawing* to screen coordinate system
void
Canvas::ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const
{
// TODO: optimize this, it should be smarter
while (num--) {
*dst = *src;
fDrawState->Transform(dst);
// NOTE: from here on, don't use the
// "*ForDrawing()" versions of the parent!
ConvertToScreen(dst);
src++;
dst++;
}
}
//! converts regions from local *drawing* to screen coordinate system
void
Canvas::ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const
{
// TODO: optimize this, it should be smarter
while (num--) {
*dst = *src;
fDrawState->Transform(dst);
// NOTE: from here on, don't use the
// "*ForDrawing()" versions of the parent!
ConvertToScreen(dst);
src++;
dst++;
}
}
//! converts a point from screen to local coordinate system
void
Canvas::ConvertFromScreenForDrawing(BPoint* point) const
{
ConvertFromScreen(point);
fDrawState->InverseTransform(point);
#if __GNUC__ >= 3
SimpleTransform transform;
#endif
_ScreenToLocalTransform(transform);
fDrawState->InverseTransform(transform);
return transform;
}
+17 -29
View File
@@ -17,6 +17,8 @@
#include <Point.h>
#include "SimpleTransform.h"
class AlphaMask;
class BGradient;
@@ -52,25 +54,10 @@ public:
void SetAlphaMask(AlphaMask* mask);
AlphaMask* GetAlphaMask() const;
void ConvertToScreenForDrawing(BPoint* point) const;
void ConvertToScreenForDrawing(BRect* rect) const;
void ConvertToScreenForDrawing(BRegion* region) const;
void ConvertToScreenForDrawing(BGradient* gradient) const;
void ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const;
void ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const;
void ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const;
void ConvertFromScreenForDrawing(BPoint* point) const;
// used when updating the pen position
virtual void ConvertToScreen(BPoint* point) const = 0;
virtual void ConvertToScreen(IntPoint* point) const = 0;
virtual void ConvertToScreen(BRect* rect) const = 0;
virtual void ConvertToScreen(IntRect* rect) const = 0;
virtual void ConvertToScreen(BRegion* region) const = 0;
virtual void ConvertFromScreen(BPoint* point) const = 0;
SimpleTransform LocalToScreenTransform() const;
SimpleTransform ScreenToLocalTransform() const;
SimpleTransform PenToScreenTransform() const;
SimpleTransform ScreenToPenTransform() const;
virtual DrawingEngine* GetDrawingEngine() const = 0;
virtual ServerPicture* GetPicture(int32 token) const = 0;
@@ -78,6 +65,12 @@ public:
virtual void ResyncDrawState() {};
virtual void UpdateCurrentDrawingRegion() {};
protected:
virtual void _LocalToScreenTransform(
SimpleTransform& transform) const = 0;
virtual void _ScreenToLocalTransform(
SimpleTransform& transform) const = 0;
protected:
DrawState* fDrawState;
};
@@ -88,22 +81,17 @@ public:
OffscreenCanvas(DrawingEngine* engine,
const DrawState& state);
// Screen and View coordinates are the same for us.
// DrawState already takes care of World<>View
// conversions.
virtual void ConvertToScreen(BPoint*) const {}
virtual void ConvertToScreen(IntPoint*) const {}
virtual void ConvertToScreen(BRect*) const {}
virtual void ConvertToScreen(IntRect*) const {}
virtual void ConvertToScreen(BRegion*) const {}
virtual void ConvertFromScreen(BPoint*) const {}
virtual DrawingEngine* GetDrawingEngine() const { return fDrawingEngine; }
virtual void RebuildClipping(bool deep) { /* TODO */ }
virtual void ResyncDrawState();
virtual ServerPicture* GetPicture(int32 token) const
{ /* TODO */ return NULL; }
protected:
virtual void _LocalToScreenTransform(SimpleTransform&) const {}
virtual void _ScreenToLocalTransform(SimpleTransform&) const {}
private:
DrawingEngine* fDrawingEngine;
};
+14 -76
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2001-2008, Haiku.
* Copyright 2001-2015, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -8,6 +8,7 @@
* Stephan Aßmus <[email protected]>
* Axel Dörfler, [email protected]
* Michael Pfeiffer <[email protected]>
* Julian Harnath <[email protected]>
*/
//! Data classes for working with BView states and draw parameters
@@ -211,7 +212,7 @@ DrawState::ReadFromLink(BPrivate::LinkReceiver& link)
ViewSetStateInfo info;
link.Read<ViewSetStateInfo>(&info);
fPenLocation = info.penLocation;
fPenSize = info.penSize;
fHighColor = info.highColor;
@@ -407,8 +408,9 @@ DrawState::GetCombinedClippingRegion(BRegion* region) const
{
if (fClippingRegion != NULL) {
BRegion localTransformedClipping(*fClippingRegion);
Transform(&localTransformedClipping);
SimpleTransform penTransform;
Transform(penTransform);
penTransform.Apply(&localTransformedClipping);
if (fPreviousState != NULL
&& fPreviousState->GetCombinedClippingRegion(region)) {
localTransformedClipping.IntersectWith(region);
@@ -438,7 +440,7 @@ DrawState::SetAlphaMask(AlphaMask* mask)
fAlphaMask = mask;
if (fAlphaMask != NULL && fPreviousState != NULL)
fAlphaMask->SetPrevious(fPreviousState->fAlphaMask);
}
@@ -453,83 +455,19 @@ DrawState::GetAlphaMask() const
void
DrawState::Transform(float* x, float* y) const
DrawState::Transform(SimpleTransform& transform) const
{
// scale relative to origin, therefore
// scale first then translate to
// origin
*x *= fCombinedScale;
*y *= fCombinedScale;
*x += fCombinedOrigin.x;
*y += fCombinedOrigin.y;
transform.AddOffset(fCombinedOrigin.x, fCombinedOrigin.y);
transform.SetScale(fCombinedScale);
}
void
DrawState::InverseTransform(float* x, float* y) const
DrawState::InverseTransform(SimpleTransform& transform) const
{
*x -= fCombinedOrigin.x;
*y -= fCombinedOrigin.y;
if (fCombinedScale != 0.0) {
*x /= fCombinedScale;
*y /= fCombinedScale;
}
}
void
DrawState::Transform(BPoint* point) const
{
Transform(&(point->x), &(point->y));
}
void
DrawState::Transform(BRect* rect) const
{
Transform(&(rect->left), &(rect->top));
Transform(&(rect->right), &(rect->bottom));
}
void
DrawState::Transform(BRegion* region) const
{
if (fCombinedScale == 1.0) {
region->OffsetBy(fCombinedOrigin.x, fCombinedOrigin.y);
} else {
// TODO: optimize some more
BRegion converted;
int32 count = region->CountRects();
for (int32 i = 0; i < count; i++) {
BRect r = region->RectAt(i);
BPoint lt(r.LeftTop());
BPoint rb(r.RightBottom());
// offset to bottom right corner of pixel before transformation
rb.x++;
rb.y++;
// apply transformation
Transform(&lt.x, &lt.y);
Transform(&rb.x, &rb.y);
// reset bottom right to pixel "index"
rb.x--;
rb.y--;
// add rect to converted region
// NOTE/TODO: the rect would not have to go
// through the whole intersection test process,
// it is guaranteed not to overlap with any rect
// already contained in the region
converted.Include(BRect(lt, rb));
}
*region = converted;
}
}
void
DrawState::InverseTransform(BPoint* point) const
{
InverseTransform(&(point->x), &(point->y));
transform.AddOffset(-fCombinedOrigin.x, -fCombinedOrigin.y);
if (fCombinedScale != 0.0)
transform.SetScale(1.0 / fCombinedScale);
}
+5 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2001-2008, Haiku.
* Copyright 2001-2015, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -7,6 +7,7 @@
* Adi Oanca <[email protected]>
* Stephan Aßmus <[email protected]>
* Axel Dörfler, [email protected]
* Julian Harnath <[email protected]>
*/
#ifndef _DRAW_STATE_H_
#define _DRAW_STATE_H_
@@ -20,6 +21,7 @@
#include "ServerFont.h"
#include "PatternHandler.h"
#include "SimpleTransform.h"
class AlphaMask;
class BRegion;
@@ -78,14 +80,8 @@ public:
AlphaMask* GetAlphaMask() const;
// coordinate transformations
void Transform(float* x, float* y) const;
void InverseTransform(float* x, float* y) const;
void Transform(BPoint* point) const;
void Transform(BRect* rect) const;
void Transform(BRegion* region) const;
void InverseTransform(BPoint* point) const;
void Transform(SimpleTransform& transform) const;
void InverseTransform(SimpleTransform& transform) const;
// color
void SetHighColor(rgb_color color);
+21 -26
View File
@@ -204,7 +204,7 @@ ShapePainter::Draw(BRect frame, bool filled)
}
BPoint offset(fCanvas->CurrentState()->PenLocation());
fCanvas->ConvertToScreenForDrawing(&offset);
fCanvas->PenToScreenTransform().Apply(&offset);
fCanvas->GetDrawingEngine()->DrawShape(frame, opCount, opList,
ptCount, ptList, filled, offset, fCanvas->Scale());
@@ -265,8 +265,9 @@ stroke_line(Canvas* canvas, BPoint start, BPoint end)
{
BPoint penPos = end;
canvas->ConvertToScreenForDrawing(&start);
canvas->ConvertToScreenForDrawing(&end);
const SimpleTransform transform = canvas->PenToScreenTransform();
transform.Apply(&start);
transform.Apply(&end);
canvas->GetDrawingEngine()->StrokeLine(start, end);
canvas->CurrentState()->SetPenLocation(penPos);
@@ -279,7 +280,7 @@ stroke_line(Canvas* canvas, BPoint start, BPoint end)
static void
stroke_rect(Canvas* canvas, BRect rect)
{
canvas->ConvertToScreenForDrawing(&rect);
canvas->PenToScreenTransform().Apply(&rect);
canvas->GetDrawingEngine()->StrokeRect(rect);
}
@@ -287,7 +288,7 @@ stroke_rect(Canvas* canvas, BRect rect)
static void
fill_rect(Canvas* canvas, BRect rect)
{
canvas->ConvertToScreenForDrawing(&rect);
canvas->PenToScreenTransform().Apply(&rect);
canvas->GetDrawingEngine()->FillRect(rect);
}
@@ -295,7 +296,7 @@ fill_rect(Canvas* canvas, BRect rect)
static void
draw_round_rect(Canvas* canvas, BRect rect, BPoint radii, bool fill)
{
canvas->ConvertToScreenForDrawing(&rect);
canvas->PenToScreenTransform().Apply(&rect);
float scale = canvas->CurrentState()->CombinedScale();
canvas->GetDrawingEngine()->DrawRoundRect(rect, radii.x * scale,
radii.y * scale, fill);
@@ -320,8 +321,7 @@ static void
stroke_bezier(Canvas* canvas, const BPoint* viewPoints)
{
BPoint points[4];
canvas->ConvertToScreenForDrawing(points, viewPoints, 4);
canvas->PenToScreenTransform().Apply(points, viewPoints, 4);
canvas->GetDrawingEngine()->DrawBezier(points, false);
}
@@ -330,8 +330,7 @@ static void
fill_bezier(Canvas* canvas, const BPoint* viewPoints)
{
BPoint points[4];
canvas->ConvertToScreenForDrawing(points, viewPoints, 4);
canvas->PenToScreenTransform().Apply(points, viewPoints, 4);
canvas->GetDrawingEngine()->DrawBezier(points, true);
}
@@ -342,7 +341,7 @@ stroke_arc(Canvas* canvas, BPoint center, BPoint radii,
{
BRect rect(center.x - radii.x, center.y - radii.y,
center.x + radii.x - 1, center.y + radii.y - 1);
canvas->ConvertToScreenForDrawing(&rect);
canvas->PenToScreenTransform().Apply(&rect);
canvas->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, false);
}
@@ -353,7 +352,7 @@ fill_arc(Canvas* canvas, BPoint center, BPoint radii,
{
BRect rect(center.x - radii.x, center.y - radii.y,
center.x + radii.x - 1, center.y + radii.y - 1);
canvas->ConvertToScreenForDrawing(&rect);
canvas->PenToScreenTransform().Apply(&rect);
canvas->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, true);
}
@@ -363,7 +362,7 @@ stroke_ellipse(Canvas* canvas, BPoint center, BPoint radii)
{
BRect rect(center.x - radii.x, center.y - radii.y,
center.x + radii.x - 1, center.y + radii.y - 1);
canvas->ConvertToScreenForDrawing(&rect);
canvas->PenToScreenTransform().Apply(&rect);
canvas->GetDrawingEngine()->DrawEllipse(rect, false);
}
@@ -373,7 +372,7 @@ fill_ellipse(Canvas* canvas, BPoint center, BPoint radii)
{
BRect rect(center.x - radii.x, center.y - radii.y,
center.x + radii.x - 1, center.y + radii.y - 1);
canvas->ConvertToScreenForDrawing(&rect);
canvas->PenToScreenTransform().Apply(&rect);
canvas->GetDrawingEngine()->DrawEllipse(rect, true);
}
@@ -391,8 +390,7 @@ stroke_polygon(Canvas* canvas, int32 numPoints,
char data[200 * sizeof(BPoint)];
BPoint* points = (BPoint*)data;
canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints);
canvas->PenToScreenTransform().Apply(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
@@ -405,8 +403,7 @@ stroke_polygon(Canvas* canvas, int32 numPoints,
if (points == NULL)
return;
canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints);
canvas->PenToScreenTransform().Apply(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
@@ -430,8 +427,7 @@ fill_polygon(Canvas* canvas, int32 numPoints,
char data[200 * sizeof(BPoint)];
BPoint* points = (BPoint*)data;
canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints);
canvas->PenToScreenTransform().Apply(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
@@ -444,8 +440,7 @@ fill_polygon(Canvas* canvas, int32 numPoints,
if (points == NULL)
return;
canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints);
canvas->PenToScreenTransform().Apply(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
@@ -486,11 +481,11 @@ draw_string(Canvas* canvas, const char* string, float deltaSpace,
BPoint location = canvas->CurrentState()->PenLocation();
escapement_delta delta = { deltaSpace, deltaNonSpace };
canvas->ConvertToScreenForDrawing(&location);
canvas->PenToScreenTransform().Apply(&location);
location = canvas->GetDrawingEngine()->DrawString(string, strlen(string),
location, &delta);
canvas->ConvertFromScreenForDrawing(&location);
canvas->PenToScreenTransform().Apply(&location);
canvas->CurrentState()->SetPenLocation(location);
// the DrawingEngine/Painter does not need to be updated, since this
// effects only the view->screen coord conversion, which is handled
@@ -511,7 +506,7 @@ draw_pixels(Canvas* canvas, BRect src, BRect dest, int32 width,
memcpy(bitmap.Bits(), data, height * bytesPerRow);
canvas->ConvertToScreenForDrawing(&dest);
canvas->PenToScreenTransform().Apply(&dest);
canvas->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest, options);
}
@@ -570,7 +565,7 @@ pop_state(Canvas* canvas)
canvas->PopState();
BPoint p(0, 0);
canvas->ConvertToScreenForDrawing(&p);
canvas->PenToScreenTransform().Apply(&p);
canvas->GetDrawingEngine()->SetDrawState(canvas->CurrentState(),
(int32)p.x, (int32)p.y);
}
+80 -50
View File
@@ -351,7 +351,7 @@ ServerWindow::_Show()
fDesktop->ShowWindow(fWindow);
if (fDirectWindowInfo && fDirectWindowInfo->IsFullScreen())
_ResizeToFullScreen();
fDesktop->LockSingleWindow();
}
@@ -1964,7 +1964,7 @@ fDesktop->LockSingleWindow();
} else {
_UpdateCurrentDrawingRegion();
BRegion region(fCurrentDrawingRegion);
fCurrentView->ConvertFromScreen(&region);
fCurrentView->ScreenToLocalTransform().Apply(&region);
fLink.AttachRegion(region);
}
fLink.Flush();
@@ -2254,8 +2254,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
info.endPoint.x, info.endPoint.y));
BPoint penPos = info.endPoint;
fCurrentView->ConvertToScreenForDrawing(&info.startPoint);
fCurrentView->ConvertToScreenForDrawing(&info.endPoint);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
transform.Apply(&info.startPoint);
transform.Apply(&info.endPoint);
drawingEngine->StrokeLine(info.startPoint, info.endPoint);
// We update the pen here because many DrawingEngine calls which
@@ -2279,7 +2281,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
fCurrentView->Name(), rect.left, rect.top, rect.right,
rect.bottom));
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->PenToScreenTransform().Apply(&rect);
drawingEngine->InvertRect(rect);
break;
}
@@ -2294,7 +2296,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
fCurrentView->Name(), rect.left, rect.top, rect.right,
rect.bottom));
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->PenToScreenTransform().Apply(&rect);
drawingEngine->StrokeRect(rect);
break;
}
@@ -2309,7 +2311,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
fCurrentView->Name(), rect.left, rect.top, rect.right,
rect.bottom));
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->PenToScreenTransform().Apply(&rect);
drawingEngine->FillRect(rect);
break;
}
@@ -2326,8 +2328,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
fCurrentView->Name(), rect.left, rect.top, rect.right,
rect.bottom));
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
transform.Apply(&rect);
transform.Apply(gradient);
drawingEngine->FillRect(rect, *gradient);
delete gradient;
break;
@@ -2356,7 +2360,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
info.viewRect.left, info.viewRect.top,
info.viewRect.right, info.viewRect.bottom));
fCurrentView->ConvertToScreenForDrawing(&info.viewRect);
fCurrentView->PenToScreenTransform().Apply(&info.viewRect);
// TODO: Unbreak...
// if ((info.options & B_WAIT_FOR_RETRACE) != 0)
@@ -2382,7 +2386,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.Read<float>(&span) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&r);
fCurrentView->PenToScreenTransform().Apply(&r);
drawingEngine->DrawArc(r, angle, span, code == AS_FILL_ARC);
break;
}
@@ -2399,8 +2403,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&r);
fCurrentView->ConvertToScreenForDrawing(gradient);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
transform.Apply(&r);
transform.Apply(gradient);
drawingEngine->FillArc(r, angle, span, *gradient);
delete gradient;
break;
@@ -2411,11 +2417,13 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_BEZIER\n",
Title()));
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
BPoint pts[4];
status_t status;
for (int32 i = 0; i < 4; i++) {
status = link.Read<BPoint>(&(pts[i]));
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
transform.Apply(&pts[i]);
}
if (status != B_OK)
break;
@@ -2428,15 +2436,17 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
GTRACE(("ServerWindow %s: Message AS_FILL_BEZIER_GRADIENT\n",
Title()));
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
BPoint pts[4];
for (int32 i = 0; i < 4; i++) {
link.Read<BPoint>(&(pts[i]));
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
transform.Apply(&pts[i]);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(gradient);
transform.Apply(gradient);
drawingEngine->FillBezier(pts, *gradient);
delete gradient;
break;
@@ -2451,7 +2461,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.Read<BRect>(&rect) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->PenToScreenTransform().Apply(&rect);
drawingEngine->DrawEllipse(rect, code == AS_FILL_ELLIPSE);
break;
}
@@ -2465,8 +2475,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
transform.Apply(&rect);
transform.Apply(gradient);
drawingEngine->FillEllipse(rect, *gradient);
delete gradient;
break;
@@ -2485,7 +2497,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.Read<float>(&yRadius) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->PenToScreenTransform().Apply(&rect);
float scale = fCurrentView->CurrentState()->CombinedScale();
drawingEngine->DrawRoundRect(rect, xRadius * scale, yRadius * scale,
code == AS_FILL_ROUNDRECT);
@@ -2504,8 +2516,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
transform.Apply(&rect);
transform.Apply(gradient);
drawingEngine->FillRoundRect(rect, xrad, yrad, *gradient);
delete gradient;
break;
@@ -2516,18 +2530,20 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_TRIANGLE\n",
Title()));
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
BPoint pts[3];
BRect rect;
for (int32 i = 0; i < 3; i++) {
link.Read<BPoint>(&(pts[i]));
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
transform.Apply(&pts[i]);
}
if (link.Read<BRect>(&rect) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
transform.Apply(&rect);
drawingEngine->DrawTriangle(pts, rect, code == AS_FILL_TRIANGLE);
break;
}
@@ -2536,18 +2552,20 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
DTRACE(("ServerWindow %s: Message AS_FILL_TRIANGLE_GRADIENT\n",
Title()));
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
BPoint pts[3];
BRect rect;
for (int32 i = 0; i < 3; i++) {
link.Read<BPoint>(&(pts[i]));
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
transform.Apply(&pts[i]);
}
link.Read<BRect>(&rect);
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
transform.Apply(&rect);
transform.Apply(gradient);
drawingEngine->FillTriangle(pts, rect, *gradient);
delete gradient;
break;
@@ -2567,11 +2585,13 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
link.Read<bool>(&isClosed);
link.Read<int32>(&pointCount);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
BPoint* pointList = new(nothrow) BPoint[pointCount];
if (link.Read(pointList, pointCount * sizeof(BPoint)) >= B_OK) {
for (int32 i = 0; i < pointCount; i++)
fCurrentView->ConvertToScreenForDrawing(&pointList[i]);
fCurrentView->ConvertToScreenForDrawing(&polyFrame);
transform.Apply(&pointList[i]);
transform.Apply(&polyFrame);
drawingEngine->DrawPolygon(pointList, pointCount, polyFrame,
code == AS_FILL_POLYGON, isClosed && pointCount > 2);
@@ -2590,14 +2610,16 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
link.Read<BRect>(&polyFrame);
link.Read<int32>(&pointCount);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
BPoint* pointList = new(nothrow) BPoint[pointCount];
BGradient* gradient;
if (link.Read(pointList, pointCount * sizeof(BPoint)) == B_OK
&& link.ReadGradient(&gradient) == B_OK) {
for (int32 i = 0; i < pointCount; i++)
fCurrentView->ConvertToScreenForDrawing(&pointList[i]);
fCurrentView->ConvertToScreenForDrawing(&polyFrame);
fCurrentView->ConvertToScreenForDrawing(gradient);
transform.Apply(&pointList[i]);
transform.Apply(&polyFrame);
transform.Apply(gradient);
drawingEngine->FillPolygon(pointList, pointCount,
polyFrame, *gradient, isClosed && pointCount > 2);
@@ -2631,8 +2653,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
= fCurrentView->CurrentState()->PenLocation();
shapeFrame.OffsetBy(screenOffset);
fCurrentView->ConvertToScreenForDrawing(&screenOffset);
fCurrentView->ConvertToScreenForDrawing(&shapeFrame);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
transform.Apply(&screenOffset);
transform.Apply(&shapeFrame);
drawingEngine->DrawShape(shapeFrame, opCount, opList, ptCount,
ptList, code == AS_FILL_SHAPE, screenOffset,
@@ -2669,9 +2693,11 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
= fCurrentView->CurrentState()->PenLocation();
shapeFrame.OffsetBy(screenOffset);
fCurrentView->ConvertToScreenForDrawing(&screenOffset);
fCurrentView->ConvertToScreenForDrawing(&shapeFrame);
fCurrentView->ConvertToScreenForDrawing(gradient);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
transform.Apply(&screenOffset);
transform.Apply(&shapeFrame);
transform.Apply(gradient);
drawingEngine->FillShape(shapeFrame, opCount, opList,
ptCount, ptList, *gradient, screenOffset,
fCurrentView->Scale());
@@ -2690,7 +2716,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.ReadRegion(&region) < B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&region);
fCurrentView->PenToScreenTransform().Apply(&region);
drawingEngine->FillRegion(region);
break;
@@ -2707,8 +2733,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&region);
fCurrentView->ConvertToScreenForDrawing(gradient);
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
transform.Apply(&region);
transform.Apply(gradient);
drawingEngine->FillRegion(region, *gradient);
delete gradient;
break;
@@ -2747,11 +2775,11 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
}
// Convert to screen coords and draw
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
for (int32 i = 0; i < lineCount; i++) {
fCurrentView->ConvertToScreenForDrawing(
&lineData[i].startPoint);
fCurrentView->ConvertToScreenForDrawing(
&lineData[i].endPoint);
transform.Apply(&lineData[i].startPoint);
transform.Apply(&lineData[i].endPoint);
}
drawingEngine->StrokeLineArray(lineCount, lineData);
@@ -2796,11 +2824,11 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
DTRACE(("ServerWindow %s: Message AS_DRAW_STRING, View: %s "
"-> %s\n", Title(), fCurrentView->Name(), string));
fCurrentView->ConvertToScreenForDrawing(&info.location);
fCurrentView->PenToScreenTransform().Apply(&info.location);
BPoint penLocation = drawingEngine->DrawString(string,
info.stringLength, info.location, delta);
fCurrentView->ConvertFromScreenForDrawing(&penLocation);
fCurrentView->ScreenToPenTransform().Apply(&penLocation);
fCurrentView->CurrentState()->SetPenLocation(penLocation);
if (string != stackString)
@@ -2853,13 +2881,15 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
DTRACE(("ServerWindow %s: Message AS_DRAW_STRING_WITH_OFFSETS, View: %s "
"-> %s\n", Title(), fCurrentView->Name(), string));
const SimpleTransform transform =
fCurrentView->PenToScreenTransform();
for (int32 i = 0; i < glyphCount; i++)
fCurrentView->ConvertToScreenForDrawing(&locations[i]);
transform.Apply(&locations[i]);
BPoint penLocation = drawingEngine->DrawString(string,
stringLength, locations);
fCurrentView->ConvertFromScreenForDrawing(&penLocation);
fCurrentView->ScreenToPenTransform().Apply(&penLocation);
fCurrentView->CurrentState()->SetPenLocation(penLocation);
break;
@@ -3703,11 +3733,11 @@ ServerWindow::_UpdateDrawState(View* view)
if (view != NULL && drawingEngine != NULL) {
BPoint leftTop(0, 0);
if (view->GetAlphaMask() != NULL) {
view->ConvertToScreen(&leftTop);
view->LocalToScreenTransform().Apply(&leftTop);
view->GetAlphaMask()->Update(view->Bounds(), leftTop);
leftTop = BPoint(0, 0);
}
view->ConvertToScreenForDrawing(&leftTop);
view->PenToScreenTransform().Apply(&leftTop);
drawingEngine->SetDrawState(view->CurrentState(), leftTop.x, leftTop.y);
}
}
+243
View File
@@ -0,0 +1,243 @@
/*
* Copyright (c) 2001-2015, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
* Stephan Aßmus <superstippi@gmx.de>
* Adrien Destugues <pulkomandy@pulkomandy.tk>
* Julian Harnath <julian.harnath@rwth-aachen.de>
*/
#ifndef SIMPLE_TRANSFORM_H
#define SIMPLE_TRANSFORM_H
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <GradientRadialFocus.h>
#include <GradientDiamond.h>
#include <GradientConic.h>
#include <Point.h>
#include <Region.h>
#include "IntPoint.h"
#include "IntRect.h"
class SimpleTransform {
public:
SimpleTransform()
:
fScale(1.0)
{
}
void AddOffset(float x, float y)
{
fOffset.x += x;
fOffset.y += y;
}
void SetScale(float scale)
{
fScale = scale;
}
void Apply(BPoint* point) const
{
_Apply(point->x, point->y);
}
void Apply(IntPoint* point) const
{
_Apply(point->x, point->y);
}
void Apply(BRect* rect) const
{
if (fScale == 1.0) {
rect->OffsetBy(fOffset.x, fOffset.y);
} else {
_Apply(rect->left, rect->top);
_Apply(rect->right, rect->bottom);
}
}
void Apply(IntRect* rect) const
{
if (fScale == 1.0) {
rect->OffsetBy(fOffset.x, fOffset.y);
} else {
_Apply(rect->left, rect->top);
_Apply(rect->right, rect->bottom);
}
}
void Apply(BRegion* region) const
{
if (fScale == 1.0) {
region->OffsetBy(fOffset.x, fOffset.y);
} else {
// TODO: optimize some more
BRegion converted;
int32 count = region->CountRects();
for (int32 i = 0; i < count; i++) {
BRect r = region->RectAt(i);
BPoint lt(r.LeftTop());
BPoint rb(r.RightBottom());
// offset to bottom right corner of pixel before transformation
rb.x++;
rb.y++;
// apply transformation
_Apply(lt.x, lt.y);
_Apply(rb.x, rb.y);
// reset bottom right to pixel "index"
rb.x--;
rb.y--;
// add rect to converted region
// NOTE/TODO: the rect would not have to go
// through the whole intersection test process,
// it is guaranteed not to overlap with any rect
// already contained in the region
converted.Include(BRect(lt, rb));
}
*region = converted;
}
}
void Apply(BGradient* gradient) const
{
switch (gradient->GetType()) {
case BGradient::TYPE_LINEAR:
{
BGradientLinear* linear = (BGradientLinear*) gradient;
BPoint start = linear->Start();
BPoint end = linear->End();
Apply(&start);
Apply(&end);
linear->SetStart(start);
linear->SetEnd(end);
break;
}
case BGradient::TYPE_RADIAL:
{
BGradientRadial* radial = (BGradientRadial*) gradient;
BPoint center = radial->Center();
Apply(&center);
radial->SetCenter(center);
break;
}
case BGradient::TYPE_RADIAL_FOCUS:
{
BGradientRadialFocus* radialFocus =
(BGradientRadialFocus*)gradient;
BPoint center = radialFocus->Center();
BPoint focal = radialFocus->Focal();
Apply(&center);
Apply(&focal);
radialFocus->SetCenter(center);
radialFocus->SetFocal(focal);
break;
}
case BGradient::TYPE_DIAMOND:
{
BGradientDiamond* diamond = (BGradientDiamond*) gradient;
BPoint center = diamond->Center();
Apply(&center);
diamond->SetCenter(center);
break;
}
case BGradient::TYPE_CONIC:
{
BGradientConic* conic = (BGradientConic*) gradient;
BPoint center = conic->Center();
Apply(&center);
conic->SetCenter(center);
break;
}
case BGradient::TYPE_NONE:
{
break;
}
}
// Make sure the gradient is fully padded so that out of bounds access
// get the correct colors
gradient->SortColorStopsByOffset();
BGradient::ColorStop* end = gradient->ColorStopAtFast(
gradient->CountColorStops() - 1);
if (end->offset != 255)
gradient->AddColor(end->color, 255);
BGradient::ColorStop* start = gradient->ColorStopAtFast(0);
if (start->offset != 0)
gradient->AddColor(start->color, 0);
gradient->SortColorStopsByOffset();
}
void Apply(BPoint* destination, const BPoint* source, int32 count) const
{
// TODO: optimize this, it should be smarter
while (count--) {
*destination = *source;
Apply(destination);
source++;
destination++;
}
}
void Apply(BRect* destination, const BRect* source, int32 count) const
{
// TODO: optimize this, it should be smarter
while (count--) {
*destination = *source;
Apply(destination);
source++;
destination++;
}
}
void Apply(BRegion* destination, const BRegion* source, int32 count) const
{
// TODO: optimize this, it should be smarter
while (count--) {
*destination = *source;
Apply(destination);
source++;
destination++;
}
}
private:
void _Apply(int32& x, int32& y) const
{
x *= (int32)fScale;
y *= (int32)fScale;
x += (int32)fOffset.x;
y += (int32)fOffset.y;
}
void _Apply(float& x, float& y) const
{
x *= fScale;
y *= fScale;
x += fOffset.x;
y += fOffset.y;
}
private:
BPoint fOffset;
float fScale;
};
#endif // SIMPLE_TRANSFORM_H
+32 -198
View File
@@ -165,7 +165,8 @@ View::ConvertToVisibleInTopView(IntRect* bounds) const
{
*bounds = *bounds & Bounds();
// NOTE: this step is necessary even if we don't have a parent!
ConvertToParent(bounds);
bounds->OffsetBy(fFrame.left - fScrollingOffset.x,
fFrame.top - fScrollingOffset.y);
if (fParent)
fParent->ConvertToVisibleInTopView(bounds);
@@ -440,7 +441,7 @@ View::ViewAt(const BPoint& where)
IntRect frame = Frame();
if (Parent() != NULL)
Parent()->ConvertToScreen(&frame);
Parent()->LocalToScreenTransform().Apply(&frame);
if (!frame.Contains(where))
return NULL;
@@ -524,7 +525,7 @@ View::_UpdateOverlayView() const
return;
IntRect destination = fBitmapDestination;
ConvertToScreen(&destination);
LocalToScreenTransform().Apply(&destination);
overlay->Configure(fBitmapSource, destination);
}
@@ -556,201 +557,34 @@ View::UpdateOverlay()
void
View::ConvertToParent(BPoint* point) const
View::_LocalToScreenTransform(SimpleTransform& transform) const
{
// remove scrolling offset and convert to parent coordinate space
point->x += fFrame.left - fScrollingOffset.x;
point->y += fFrame.top - fScrollingOffset.y;
const View* view = this;
int32 offsetX = 0;
int32 offsetY = 0;
do {
offsetX += view->fFrame.left - view->fScrollingOffset.x;
offsetY += view->fFrame.top - view->fScrollingOffset.y;
view = view->fParent;
} while (view != NULL);
transform.AddOffset(offsetX, offsetY);
}
void
View::ConvertToParent(IntPoint* point) const
View::_ScreenToLocalTransform(SimpleTransform& transform) const
{
// remove scrolling offset and convert to parent coordinate space
point->x += fFrame.left - fScrollingOffset.x;
point->y += fFrame.top - fScrollingOffset.y;
}
const View* view = this;
int32 offsetX = 0;
int32 offsetY = 0;
do {
offsetX += view->fScrollingOffset.x - view->fFrame.left;
offsetY += view->fScrollingOffset.y - view->fFrame.top;
view = view->fParent;
} while (view != NULL);
void
View::ConvertToParent(BRect* rect) const
{
// remove scrolling offset and convert to parent coordinate space
rect->OffsetBy(fFrame.left - fScrollingOffset.x,
fFrame.top - fScrollingOffset.y);
}
void
View::ConvertToParent(IntRect* rect) const
{
// remove scrolling offset and convert to parent coordinate space
rect->OffsetBy(fFrame.left - fScrollingOffset.x,
fFrame.top - fScrollingOffset.y);
}
void
View::ConvertToParent(BRegion* region) const
{
// remove scrolling offset and convert to parent coordinate space
region->OffsetBy(fFrame.left - fScrollingOffset.x,
fFrame.top - fScrollingOffset.y);
}
void
View::ConvertFromParent(BPoint* point) const
{
// convert from parent coordinate space amd add scrolling offset
point->x += fScrollingOffset.x - fFrame.left;
point->y += fScrollingOffset.y - fFrame.top;
}
void
View::ConvertFromParent(IntPoint* point) const
{
// convert from parent coordinate space amd add scrolling offset
point->x += fScrollingOffset.x - fFrame.left;
point->y += fScrollingOffset.y - fFrame.top;
}
void
View::ConvertFromParent(BRect* rect) const
{
// convert from parent coordinate space amd add scrolling offset
rect->OffsetBy(fScrollingOffset.x - fFrame.left,
fScrollingOffset.y - fFrame.top);
}
void
View::ConvertFromParent(IntRect* rect) const
{
// convert from parent coordinate space amd add scrolling offset
rect->OffsetBy(fScrollingOffset.x - fFrame.left,
fScrollingOffset.y - fFrame.top);
}
void
View::ConvertFromParent(BRegion* region) const
{
// convert from parent coordinate space amd add scrolling offset
region->OffsetBy(fScrollingOffset.x - fFrame.left,
fScrollingOffset.y - fFrame.top);
}
//! converts a point from local to screen coordinate system
void
View::ConvertToScreen(BPoint* pt) const
{
ConvertToParent(pt);
if (fParent)
fParent->ConvertToScreen(pt);
}
//! converts a point from local to screen coordinate system
void
View::ConvertToScreen(IntPoint* pt) const
{
ConvertToParent(pt);
if (fParent)
fParent->ConvertToScreen(pt);
}
//! converts a rect from local to screen coordinate system
void
View::ConvertToScreen(BRect* rect) const
{
BPoint offset(0.0, 0.0);
ConvertToScreen(&offset);
rect->OffsetBy(offset);
}
//! converts a rect from local to screen coordinate system
void
View::ConvertToScreen(IntRect* rect) const
{
BPoint offset(0.0, 0.0);
ConvertToScreen(&offset);
rect->OffsetBy(offset);
}
//! converts a region from local to screen coordinate system
void
View::ConvertToScreen(BRegion* region) const
{
BPoint offset(0.0, 0.0);
ConvertToScreen(&offset);
region->OffsetBy((int)offset.x, (int)offset.y);
}
//! converts a point from screen to local coordinate system
void
View::ConvertFromScreen(BPoint* pt) const
{
ConvertFromParent(pt);
if (fParent)
fParent->ConvertFromScreen(pt);
}
//! converts a point from screen to local coordinate system
void
View::ConvertFromScreen(IntPoint* pt) const
{
ConvertFromParent(pt);
if (fParent)
fParent->ConvertFromScreen(pt);
}
//! converts a rect from screen to local coordinate system
void
View::ConvertFromScreen(BRect* rect) const
{
BPoint offset(0.0, 0.0);
ConvertFromScreen(&offset);
rect->OffsetBy(offset.x, offset.y);
}
//! converts a rect from screen to local coordinate system
void
View::ConvertFromScreen(IntRect* rect) const
{
BPoint offset(0.0, 0.0);
ConvertFromScreen(&offset);
rect->OffsetBy((int)offset.x, (int)offset.y);
}
//! converts a region from screen to local coordinate system
void
View::ConvertFromScreen(BRegion* region) const
{
BPoint offset(0.0, 0.0);
ConvertFromScreen(&offset);
region->OffsetBy((int)offset.x, (int)offset.y);
transform.AddOffset(offsetX, offsetY);
}
@@ -775,7 +609,7 @@ View::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
// local clipping to see which parts need invalidation
IntRect oldVisibleBounds(newVisibleBounds);
oldVisibleBounds.OffsetBy(-x, -y);
ConvertToScreen(&oldVisibleBounds);
LocalToScreenTransform().Apply(&oldVisibleBounds);
ConvertToVisibleInTopView(&newVisibleBounds);
@@ -788,7 +622,7 @@ View::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
IntRect oldVisibleBounds(Bounds());
IntRect newVisibleBounds(oldVisibleBounds);
oldVisibleBounds.OffsetBy(-x, -y);
ConvertToScreen(&oldVisibleBounds);
LocalToScreenTransform().Apply(&oldVisibleBounds);
// NOTE: using ConvertToVisibleInTopView()
// instead of ConvertToScreen()! see below
@@ -875,7 +709,7 @@ View::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
}
}
ConvertToScreen(dirty);
LocalToScreenTransform().Apply(dirty);
dirtyRegion->Include(dirty);
}
fWindow->RecycleRegion(dirty);
@@ -1171,7 +1005,7 @@ View::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
// draw view bitmap
// TODO: support other options!
BRect rect = fBitmapDestination;
ConvertToScreenForDrawing(&rect);
PenToScreenTransform().Apply(&rect);
align_rect_to_pixels(&rect);
@@ -1406,7 +1240,7 @@ View::AddTokensForViewsInRegion(BPrivate::PortLink& link, BRegion& region,
// This check will prevent descending the view hierarchy
// any further than necessary
IntRect screenBounds(Bounds());
ConvertToScreen(&screenBounds);
LocalToScreenTransform().Apply(&screenBounds);
if (!region.Intersects((clipping_rect)screenBounds))
return;
@@ -1537,7 +1371,7 @@ View::ScreenAndUserClipping(BRegion* windowContentClipping, bool force) const
if (fScreenAndUserClipping == NULL)
return fScreenClipping;
ConvertToScreen(fScreenAndUserClipping);
LocalToScreenTransform().Apply(fScreenAndUserClipping);
fScreenAndUserClipping->IntersectWith(
&_ScreenClipping(windowContentClipping, force));
return *fScreenAndUserClipping;
@@ -1578,7 +1412,7 @@ View::_ScreenClipping(BRegion* windowContentClipping, bool force) const
{
if (!fScreenClippingValid || force) {
fScreenClipping = fLocalClipping;
ConvertToScreen(&fScreenClipping);
LocalToScreenTransform().Apply(&fScreenClipping);
// see if parts of our bounds are hidden underneath
// the parent, the local clipping does not account for this
+6 -25
View File
@@ -111,31 +111,7 @@ public:
View* ViewAt(const BPoint& where);
// coordinate conversion
void ConvertToParent(BPoint* point) const;
void ConvertToParent(IntPoint* point) const;
void ConvertToParent(BRect* rect) const;
void ConvertToParent(IntRect* rect) const;
void ConvertToParent(BRegion* region) const;
void ConvertFromParent(BPoint* point) const;
void ConvertFromParent(IntPoint* point) const;
void ConvertFromParent(BRect* rect) const;
void ConvertFromParent(IntRect* rect) const;
void ConvertFromParent(BRegion* region) const;
void ConvertToScreen(BPoint* point) const;
void ConvertToScreen(IntPoint* point) const;
void ConvertToScreen(BRect* rect) const;
void ConvertToScreen(IntRect* rect) const;
void ConvertToScreen(BRegion* region) const;
void ConvertFromScreen(BPoint* point) const;
void ConvertFromScreen(IntPoint* point) const;
void ConvertFromScreen(BRect* rect) const;
void ConvertFromScreen(IntRect* rect) const;
void ConvertFromScreen(BRegion* region) const;
public:
void MoveBy(int32 dx, int32 dy,
BRegion* dirtyRegion);
@@ -235,6 +211,11 @@ public:
#endif
protected:
virtual void _LocalToScreenTransform(
SimpleTransform& transform) const;
virtual void _ScreenToLocalTransform(
SimpleTransform& transform) const;
BRegion& _ScreenClipping(BRegion* windowContentClipping,
bool force = false) const;
void _MoveScreenClipping(int32 x, int32 y,
+1 -1
View File
@@ -817,7 +817,7 @@ Window::InvalidateView(View* view, BRegion& viewRegion)
if (!fContentRegionValid)
_UpdateContentRegion();
view->ConvertToScreen(&viewRegion);
view->LocalToScreenTransform().Apply(&viewRegion);
viewRegion.IntersectWith(&VisibleContentRegion());
if (viewRegion.CountRects() > 0) {
viewRegion.IntersectWith(
+3 -3
View File
@@ -90,7 +90,7 @@ WorkspacesView::_WorkspaceAt(int32 i)
_GetGrid(columns, rows);
BRect frame = Bounds();
ConvertToScreen(&frame);
LocalToScreenTransform().Apply(&frame);
int32 width = frame.IntegerWidth() / columns;
int32 height = frame.IntegerHeight() / rows;
@@ -356,7 +356,7 @@ void
WorkspacesView::_Invalidate() const
{
BRect frame = Bounds();
ConvertToScreen(&frame);
LocalToScreenTransform().Apply(&frame);
BRegion region(frame);
Window()->MarkContentDirty(region);
@@ -385,7 +385,7 @@ WorkspacesView::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
drawingEngine->ConstrainClippingRegion(&gridRegion);
BRect frame = Bounds();
ConvertToScreen(&frame);
LocalToScreenTransform().Apply(&frame);
// horizontal lines