[haiku-commits] haiku: hrev46817 - src/servers/app src/kits/interface headers/private/interface headers

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 4 Feb 2014 22:53:29 +0100 (CET)

hrev46817 adds 1 changeset to branch 'master'
old head: 339a01811283149b14aa5ecd793f934a476b6f86
new head: a6db6bd40fe3492fd3104dba560f0e3ff61d388d
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=a6db6bd+%5E339a018

----------------------------------------------------------------------------

a6db6bd: Added WIP support for affine transformations to BViews.
  
  Everything untested, but compiles, so it must work. The idea is to introduce
  BAffineTransform additionally to the existing Origin and Scale properties of
  BViews. One may use it in parallel or as an alternative. Painter in app_server
  is not yet aware of the additional transformation. It is however already used
  to transform drawing coordinates. It probably needs to work differently,
  perhaps only in Painter and AGGTextRenderer.

                                      [ Stephan Aßmus <superstippi@xxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev46817
Commit:      a6db6bd40fe3492fd3104dba560f0e3ff61d388d
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a6db6bd
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Tue Feb  4 21:46:55 2014 UTC

----------------------------------------------------------------------------

12 files changed, 258 insertions(+), 61 deletions(-)
headers/os/interface/View.h                   |  7 ++
headers/private/app/ServerProtocol.h          |  4 ++
headers/private/app/ServerProtocolStructs.h   |  2 +
headers/private/interface/PictureDataWriter.h |  2 +
headers/private/interface/PictureProtocol.h   | 51 +++++++-------
headers/private/interface/ViewPrivate.h       |  9 ++-
src/kits/interface/PictureDataWriter.cpp      | 14 ++++
src/kits/interface/PicturePlayer.cpp          | 16 ++++-
src/kits/interface/View.cpp                   | 75 ++++++++++++++++++---
src/servers/app/DrawState.cpp                 | 82 +++++++++++++++++------
src/servers/app/DrawState.h                   | 11 ++-
src/servers/app/ServerWindow.cpp              | 46 ++++++++++++-

----------------------------------------------------------------------------

diff --git a/headers/os/interface/View.h b/headers/os/interface/View.h
index 6b89273..b2e183c 100644
--- a/headers/os/interface/View.h
+++ b/headers/os/interface/View.h
@@ -6,6 +6,7 @@
 #define        _VIEW_H
 
 
+#include <AffineTransform.h>
 #include <Alignment.h>
 #include <Font.h>
 #include <Handler.h>
@@ -285,6 +286,12 @@ public:
                        void                            SetOrigin(float x, 
float y);
                        BPoint                          Origin() const;
 
+                                                               // Works in 
addition to Origin and Scale.
+                                                               // May be used 
in parallel or as a much
+                                                               // more 
powerful alternative.
+                       void                            
SetTransform(BAffineTransform transform);
+                       BAffineTransform        Transform() const;
+
                        void                            PushState();
                        void                            PopState();
 
diff --git a/headers/private/app/ServerProtocol.h 
b/headers/private/app/ServerProtocol.h
index ca6c19a..782a578 100644
--- a/headers/private/app/ServerProtocol.h
+++ b/headers/private/app/ServerProtocol.h
@@ -341,6 +341,10 @@ enum {
        AS_DUMP_ALLOCATOR,
        AS_DUMP_BITMAPS,
 
+       // transformation in addition to origin/scale
+       AS_VIEW_SET_TRANSFORM,
+       AS_VIEW_GET_TRANSFORM,
+
        AS_LAST_CODE
 };
 
diff --git a/headers/private/app/ServerProtocolStructs.h 
b/headers/private/app/ServerProtocolStructs.h
index 12f70a1..8534733 100644
--- a/headers/private/app/ServerProtocolStructs.h
+++ b/headers/private/app/ServerProtocolStructs.h
@@ -9,6 +9,7 @@
 #define APP_SERVER_PROTOCOL_STRUCTS_H
 
 
+#include <AffineTransform.h>
 #include <Rect.h>
 
 
@@ -21,6 +22,7 @@ struct ViewSetStateInfo {
        drawing_mode                            drawingMode;
        BPoint                                          origin;
        float                                           scale;
+       BAffineTransform                        transform;
        join_mode                                       lineJoin;
        cap_mode                                        lineCap;
        float                                           miterLimit;
diff --git a/headers/private/interface/PictureDataWriter.h 
b/headers/private/interface/PictureDataWriter.h
index 573f6f3..9015c05 100644
--- a/headers/private/interface/PictureDataWriter.h
+++ b/headers/private/interface/PictureDataWriter.h
@@ -9,6 +9,7 @@
 #define _PICTURE_DATA_WRITER_H
 
 
+#include <AffineTransform.h>
 #include <InterfaceDefs.h>
 #include <Font.h>
 #include <OS.h>
@@ -35,6 +36,7 @@ public:
        status_t WriteSetPenSize(const float &penSize);
        status_t WriteSetLineMode(const cap_mode &cap, const join_mode &join, 
const float &miterLimit); 
        status_t WriteSetScale(const float &scale);
+       status_t WriteSetTransform(BAffineTransform transform);
        status_t WriteSetPattern(const pattern &pat);
        status_t WriteSetClipping(const BRegion &region);
        status_t WriteClearClipping();
diff --git a/headers/private/interface/PictureProtocol.h 
b/headers/private/interface/PictureProtocol.h
index 08d9ca0..f83b53d 100644
--- a/headers/private/interface/PictureProtocol.h
+++ b/headers/private/interface/PictureProtocol.h
@@ -2,40 +2,40 @@
 #define _PICTUREPROTOCOL_H
 
 enum {
-       B_PIC_MOVE_PEN_BY               = 0x0010,
+       B_PIC_MOVE_PEN_BY                       = 0x0010,
 
-       B_PIC_STROKE_LINE               = 0x0100,
-       B_PIC_STROKE_RECT               = 0x0101,
-       B_PIC_FILL_RECT                 = 0x0102,
+       B_PIC_STROKE_LINE                       = 0x0100,
+       B_PIC_STROKE_RECT                       = 0x0101,
+       B_PIC_FILL_RECT                         = 0x0102,
        B_PIC_STROKE_ROUND_RECT         = 0x0103,
        B_PIC_FILL_ROUND_RECT           = 0x0104,
-       B_PIC_STROKE_BEZIER             = 0x0105,
-       B_PIC_FILL_BEZIER               = 0x0106,
+       B_PIC_STROKE_BEZIER                     = 0x0105,
+       B_PIC_FILL_BEZIER                       = 0x0106,
        B_PIC_STROKE_POLYGON            = 0x010B,
-       B_PIC_FILL_POLYGON              = 0x010C,
-       B_PIC_STROKE_SHAPE              = 0x010D,
-       B_PIC_FILL_SHAPE                = 0x010E,
-       B_PIC_DRAW_STRING               = 0x010F,
-       B_PIC_DRAW_PIXELS               = 0x0110,
-       B_PIC_DRAW_PICTURE              = 0x0112,
-       B_PIC_STROKE_ARC                = 0x0113,
-       B_PIC_FILL_ARC                  = 0x0114,
+       B_PIC_FILL_POLYGON                      = 0x010C,
+       B_PIC_STROKE_SHAPE                      = 0x010D,
+       B_PIC_FILL_SHAPE                        = 0x010E,
+       B_PIC_DRAW_STRING                       = 0x010F,
+       B_PIC_DRAW_PIXELS                       = 0x0110,
+       B_PIC_DRAW_PICTURE                      = 0x0112,
+       B_PIC_STROKE_ARC                        = 0x0113,
+       B_PIC_FILL_ARC                          = 0x0114,
        B_PIC_STROKE_ELLIPSE            = 0x0115,
-       B_PIC_FILL_ELLIPSE              = 0x0116,
+       B_PIC_FILL_ELLIPSE                      = 0x0116,
 
        B_PIC_ENTER_STATE_CHANGE        = 0x0200,
        B_PIC_SET_CLIPPING_RECTS        = 0x0201,
        B_PIC_CLIP_TO_PICTURE           = 0x0202,
-       B_PIC_PUSH_STATE                = 0x0203,
-       B_PIC_POP_STATE                 = 0x0204,
+       B_PIC_PUSH_STATE                        = 0x0203,
+       B_PIC_POP_STATE                         = 0x0204,
        B_PIC_CLEAR_CLIPPING_RECTS      = 0x0205,
 
-       B_PIC_SET_ORIGIN                = 0x0300,
+       B_PIC_SET_ORIGIN                        = 0x0300,
        B_PIC_SET_PEN_LOCATION          = 0x0301,
        B_PIC_SET_DRAWING_MODE          = 0x0302,
-       B_PIC_SET_LINE_MODE             = 0x0303,
-       B_PIC_SET_PEN_SIZE              = 0x0304,
-       B_PIC_SET_SCALE                 = 0x0305,
+       B_PIC_SET_LINE_MODE                     = 0x0303,
+       B_PIC_SET_PEN_SIZE                      = 0x0304,
+       B_PIC_SET_SCALE                         = 0x0305,
        B_PIC_SET_FORE_COLOR            = 0x0306,
        B_PIC_SET_BACK_COLOR            = 0x0307,
        B_PIC_SET_STIPLE_PATTERN        = 0x0308,
@@ -46,15 +46,16 @@ enum {
        B_PIC_SET_FONT_SPACING          = 0x0382,
        B_PIC_SET_FONT_ENCODING         = 0x0383,
        B_PIC_SET_FONT_FLAGS            = 0x0384,
-       B_PIC_SET_FONT_SIZE             = 0x0385,
+       B_PIC_SET_FONT_SIZE                     = 0x0385,
        B_PIC_SET_FONT_ROTATE           = 0x0386,
        B_PIC_SET_FONT_SHEAR            = 0x0387,
-       B_PIC_SET_FONT_BPP              = 0x0388,
-       B_PIC_SET_FONT_FACE             = 0x0389,
+       B_PIC_SET_FONT_BPP                      = 0x0388,
+       B_PIC_SET_FONT_FACE                     = 0x0389,
+       B_PIC_SET_TRANSFORM                     = 0x0390,
 };
 
 
-const static uint32 kOpsTableSize = 48;
+const static uint32 kOpsTableSize = 49;
 
 
 #endif
diff --git a/headers/private/interface/ViewPrivate.h 
b/headers/private/interface/ViewPrivate.h
index cd32f93..4be0f77 100644
--- a/headers/private/interface/ViewPrivate.h
+++ b/headers/private/interface/ViewPrivate.h
@@ -39,8 +39,9 @@ enum {
        B_VIEW_LOW_COLOR_BIT            = 0x00008000,
        B_VIEW_VIEW_COLOR_BIT           = 0x00010000,
        B_VIEW_PATTERN_BIT                      = 0x00020000,
+       B_VIEW_TRANSFORM_BIT            = 0x00040000,
 
-       B_VIEW_ALL_BITS                         = 0x0003ffff,
+       B_VIEW_ALL_BITS                         = 0x0007ffff,
 
        // these used for archiving only
        B_VIEW_RESIZE_BIT                       = 0x00001000,
@@ -111,7 +112,11 @@ class ViewState {
                ::drawing_mode          drawing_mode;
                BRegion                         clipping_region;
                bool                            clipping_region_used;
+
+               // transformation
                BPoint                          origin;
+               float                           scale;
+               BAffineTransform        transform;
 
                // line modes
                join_mode                       line_join;
@@ -122,8 +127,6 @@ class ViewState {
                source_alpha            alpha_source_mode;
                alpha_function          alpha_function_mode;
 
-               float                           scale;
-
                // fonts
                BFont                           font;
                uint16                          font_flags;
diff --git a/src/kits/interface/PictureDataWriter.cpp 
b/src/kits/interface/PictureDataWriter.cpp
index 3215415..21b6410 100644
--- a/src/kits/interface/PictureDataWriter.cpp
+++ b/src/kits/interface/PictureDataWriter.cpp
@@ -158,6 +158,20 @@ PictureDataWriter::WriteSetScale(const float &scale)
 
 
 status_t
+PictureDataWriter::WriteSetTransform(BAffineTransform transform)
+{
+       try {
+               BeginOp(B_PIC_SET_TRANSFORM);
+               Write<BAffineTransform>(transform);
+               EndOp();
+       } catch (status_t &status) {
+               return status;  
+       }
+       return B_OK;
+}
+
+
+status_t
 PictureDataWriter::WriteSetPattern(const pattern &pat)
 {
        try {
diff --git a/src/kits/interface/PicturePlayer.cpp 
b/src/kits/interface/PicturePlayer.cpp
index 5a1fcbd..f337bc1 100644
--- a/src/kits/interface/PicturePlayer.cpp
+++ b/src/kits/interface/PicturePlayer.cpp
@@ -10,16 +10,19 @@
 
 /**    PicturePlayer is used to play picture data. */
 
+#include <PicturePlayer.h>
+
 #include <stdio.h>
 #include <string.h>
 
-#include <PicturePlayer.h>
+#include <AffineTransform.h>
 #include <PictureProtocol.h>
-
 #include <Shape.h>
 
+
 using BPrivate::PicturePlayer;
 
+
 typedef void (*fnc)(void*);
 typedef void (*fnc_BPoint)(void*, BPoint);
 typedef void (*fnc_BPointBPoint)(void*, BPoint, BPoint);
@@ -43,6 +46,7 @@ typedef void (*fnc_DrawPixels)(void *, BRect, BRect, int32, 
int32, int32,
                                                           int32, int32, const 
void *);
 typedef void (*fnc_DrawPicture)(void *, BPoint, int32);
 typedef void (*fnc_BShape)(void*, BShape*);
+typedef void (*fnc_BAffineTransform)(void*, BAffineTransform);
 
 
 static void
@@ -91,6 +95,7 @@ PictureOpToString(int op)
                RETURN_STRING(B_PIC_SET_LINE_MODE);
                RETURN_STRING(B_PIC_SET_PEN_SIZE);
                RETURN_STRING(B_PIC_SET_SCALE);
+               RETURN_STRING(B_PIC_SET_TRANSFORM);
                RETURN_STRING(B_PIC_SET_FORE_COLOR);
                RETURN_STRING(B_PIC_SET_BACK_COLOR);
                RETURN_STRING(B_PIC_SET_STIPLE_PATTERN);
@@ -533,6 +538,13 @@ PicturePlayer::Play(void **callBackTable, int32 
tableEntries, void *userData)
                                break;
                        }
 
+                       case B_PIC_SET_TRANSFORM:
+                       {
+                               
((fnc_BAffineTransform)functionTable[48])(userData,
+                                       *reinterpret_cast<const 
BAffineTransform *>(data));
+                               break;
+                       }
+
                        default:
                                break;
                }
diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp
index f20295d..84da3ed 100644
--- a/src/kits/interface/View.cpp
+++ b/src/kits/interface/View.cpp
@@ -221,6 +221,7 @@ ViewState::UpdateServerState(BPrivate::PortLink &link)
        info.drawingMode = drawing_mode;
        info.origin = origin;
        info.scale = scale;
+       info.transform = transform;
        info.lineJoin = line_join;
        info.lineCap = line_cap;
        info.miterLimit = miter_limit;
@@ -284,6 +285,7 @@ ViewState::UpdateFrom(BPrivate::PortLink &link)
        drawing_mode = info.viewStateInfo.drawingMode;
        origin = info.viewStateInfo.origin;
        scale = info.viewStateInfo.scale;
+       transform = info.viewStateInfo.transform;
        line_join = info.viewStateInfo.lineJoin;
        line_cap = info.viewStateInfo.lineCap;
        miter_limit = info.viewStateInfo.miterLimit;
@@ -467,6 +469,14 @@ BView::BView(BMessage* archive)
        if (archive->FindPoint("_origin", &origin) == B_OK)
                SetOrigin(origin);
 
+       float scale;
+       if (archive->FindFloat("_scale", &scale) == B_OK)
+               SetScale(scale);
+
+       BAffineTransform transform;
+       if (archive->FindFlat("_transform", &transform) == B_OK)
+               SetTransform(transform);
+
        float penSize;
        if (archive->FindFloat("_psize", &penSize) == B_OK)
                SetPenSize(penSize);
@@ -584,6 +594,14 @@ BView::Archive(BMessage* data, bool deep) const
        if (ret == B_OK && (fState->archiving_flags & B_VIEW_ORIGIN_BIT) != 0)
                ret = data->AddPoint("_origin", Origin());
 
+       if (ret == B_OK && (fState->archiving_flags & B_VIEW_SCALE_BIT) != 0)
+               ret = data->AddFloat("_scale", Scale());
+
+       if (ret == B_OK && (fState->archiving_flags & B_VIEW_TRANSFORM_BIT) != 
0) {
+               BAffineTransform transform = Transform();
+               ret = data->AddFlat("_transform", &transform);
+       }
+
        if (ret == B_OK && (fState->archiving_flags & B_VIEW_PEN_SIZE_BIT) != 0)
                ret = data->AddFloat("_psize", PenSize());
 
@@ -1743,10 +1761,12 @@ BView::PushState()
 
        fOwner->fLink->StartMessage(AS_VIEW_PUSH_STATE);
 
-       // initialize origin and scale
-       fState->valid_flags |= B_VIEW_SCALE_BIT | B_VIEW_ORIGIN_BIT;
+       // initialize origin, scale and transform, new states start "clean".
+       fState->valid_flags |= B_VIEW_SCALE_BIT | B_VIEW_ORIGIN_BIT
+               | B_VIEW_TRANSFORM_BIT;
        fState->scale = 1.0f;
        fState->origin.Set(0, 0);
+       fState->transform.Reset();
 }
 
 
@@ -1805,12 +1825,10 @@ BView::Origin() const
                fOwner->fLink->StartMessage(AS_VIEW_GET_ORIGIN);
 
                int32 code;
-               if (fOwner->fLink->FlushWithReply(code) == B_OK
-                       && code == B_OK) {
+               if (fOwner->fLink->FlushWithReply(code) == B_OK && code == B_OK)
                        fOwner->fLink->Read<BPoint>(&fState->origin);
 
-                       fState->valid_flags |= B_VIEW_ORIGIN_BIT;
-               }
+               fState->valid_flags |= B_VIEW_ORIGIN_BIT;
        }
 
        return fState->origin;
@@ -1846,8 +1864,7 @@ BView::Scale() const
                fOwner->fLink->StartMessage(AS_VIEW_GET_SCALE);
 
                int32 code;
-               if (fOwner->fLink->FlushWithReply(code) == B_OK
-                       && code == B_OK)
+               if (fOwner->fLink->FlushWithReply(code) == B_OK && code == B_OK)
                        fOwner->fLink->Read<float>(&fState->scale);
 
                fState->valid_flags |= B_VIEW_SCALE_BIT;
@@ -1858,6 +1875,45 @@ BView::Scale() const
 
 
 void
+BView::SetTransform(BAffineTransform transform)
+{
+       if (fState->IsValid(B_VIEW_TRANSFORM_BIT) && transform == 
fState->transform)
+               return;
+
+       if (fOwner != NULL) {
+               _CheckLockAndSwitchCurrent();
+
+               fOwner->fLink->StartMessage(AS_VIEW_SET_TRANSFORM);
+               fOwner->fLink->Attach<BAffineTransform>(transform);
+
+               fState->valid_flags |= B_VIEW_TRANSFORM_BIT;
+       }
+
+       fState->transform = transform;
+       fState->archiving_flags |= B_VIEW_TRANSFORM_BIT;
+}
+
+
+BAffineTransform
+BView::Transform() const
+{
+       if (!fState->IsValid(B_VIEW_TRANSFORM_BIT) && fOwner != NULL) {
+               _CheckLockAndSwitchCurrent();
+
+               fOwner->fLink->StartMessage(AS_VIEW_GET_TRANSFORM);
+
+               int32 code;
+               if (fOwner->fLink->FlushWithReply(code) == B_OK && code == B_OK)
+                       
fOwner->fLink->Read<BAffineTransform>(&fState->transform);
+
+               fState->valid_flags |= B_VIEW_TRANSFORM_BIT;
+       }
+
+       return fState->transform;
+}
+
+
+void
 BView::SetLineMode(cap_mode lineCap, join_mode lineJoin, float miterLimit)
 {
        if (fState->IsValid(B_VIEW_LINE_MODES_BIT)
@@ -1918,8 +1974,7 @@ BView::LineMiterLimit() const
                fOwner->fLink->StartMessage(AS_VIEW_GET_LINE_MODE);
 
                int32 code;
-               if (fOwner->fLink->FlushWithReply(code) == B_OK
-                       && code == B_OK) {
+               if (fOwner->fLink->FlushWithReply(code) == B_OK && code == 
B_OK) {
 
                        ViewSetLineModeInfo info;
                        fOwner->fLink->Read<ViewSetLineModeInfo>(&info);
diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp
index 767d776..a673aea4 100644
--- a/src/servers/app/DrawState.cpp
+++ b/src/servers/app/DrawState.cpp
@@ -30,10 +30,12 @@ using std::nothrow;
 
 DrawState::DrawState()
        :
-       fOrigin(0.0, 0.0),
-       fCombinedOrigin(0.0, 0.0),
-       fScale(1.0),
-       fCombinedScale(1.0),
+       fOrigin(0.0f, 0.0f),
+       fCombinedOrigin(0.0f, 0.0f),
+       fScale(1.0f),
+       fCombinedScale(1.0f),
+       fTransform(),
+       fCombinedTransform(),
        fClippingRegion(NULL),
        fAlphaMask(NULL),
 
@@ -45,8 +47,8 @@ DrawState::DrawState()
        fAlphaSrcMode(B_PIXEL_ALPHA),
        fAlphaFncMode(B_ALPHA_OVERLAY),
 
-       fPenLocation(0.0, 0.0),
-       fPenSize(1.0),
+       fPenLocation(0.0f, 0.0f),
+       fPenSize(1.0f),
 
        fFontAliasing(false),
        fSubPixelPrecise(false),
@@ -65,6 +67,8 @@ DrawState::DrawState(const DrawState& other)
        fCombinedOrigin(other.fCombinedOrigin),
        fScale(other.fScale),
        fCombinedScale(other.fCombinedScale),
+       fTransform(other.fTransform),
+       fCombinedTransform(other.fCombinedTransform),
        fClippingRegion(NULL),
        fAlphaMask(NULL),
 
@@ -115,6 +119,7 @@ DrawState::PushState()
                // Prepare state as derived from this state
                next->fOrigin = BPoint(0.0, 0.0);
                next->fScale = 1.0;
+               next->fTransform.Reset();
                next->fPreviousState = this;
                next->SetAlphaMask(fAlphaMask);
        }
@@ -212,6 +217,7 @@ DrawState::ReadFromLink(BPrivate::LinkReceiver& link)
        fDrawingMode = info.drawingMode;
        fOrigin = info.origin;
        fScale = info.scale;
+       fTransform = info.transform;
        fLineJoinMode = info.lineJoin;
        fLineCapMode = info.lineCap;
        fMiterLimit = info.miterLimit;
@@ -222,9 +228,11 @@ DrawState::ReadFromLink(BPrivate::LinkReceiver& link)
        if (fPreviousState != NULL) {
                fCombinedOrigin = fPreviousState->fCombinedOrigin + fOrigin;
                fCombinedScale = fPreviousState->fCombinedScale * fScale;
+               fCombinedTransform = fPreviousState->fCombinedTransform * 
fTransform;
        } else {
                fCombinedOrigin = fOrigin;
                fCombinedScale = fScale;
+               fCombinedTransform = fTransform;
        }
 
 
@@ -273,6 +281,7 @@ DrawState::WriteToLink(BPrivate::LinkSender& link) const
        info.viewStateInfo.drawingMode = fDrawingMode;
        info.viewStateInfo.origin = fOrigin;
        info.viewStateInfo.scale = fScale;
+       info.viewStateInfo.transform = fTransform;
        info.viewStateInfo.lineJoin = fLineJoinMode;
        info.viewStateInfo.lineCap = fLineCapMode;
        info.viewStateInfo.miterLimit = fMiterLimit;
@@ -319,21 +328,39 @@ DrawState::SetOrigin(BPoint origin)
 void
 DrawState::SetScale(float scale)
 {
-       if (fScale != scale) {
-               fScale = scale;
+       if (fScale == scale)
+               return;
 
-               // NOTE: the scales of earlier states are never expected to
-               // change, only the topmost state ever changes
-               if (fPreviousState != NULL)
-                       fCombinedScale = fPreviousState->fCombinedScale * 
fScale;
-               else
-                       fCombinedScale = fScale;
+       fScale = scale;
 
-               // update font size
-               // NOTE: This is what makes the call potentially expensive,
-               // hence the introductory check
-               fFont.SetSize(fUnscaledFontSize * fCombinedScale);
-       }
+       // NOTE: the scales of earlier states are never expected to
+       // change, only the topmost state ever changes
+       if (fPreviousState != NULL)
+               fCombinedScale = fPreviousState->fCombinedScale * fScale;
+       else
+               fCombinedScale = fScale;
+
+       // update font size
+       // NOTE: This is what makes the call potentially expensive,
+       // hence the introductory check
+       fFont.SetSize(fUnscaledFontSize * fCombinedScale);
+}
+
+
+void
+DrawState::SetTransform(BAffineTransform transform)
+{
+       if (fTransform == transform)
+               return;
+
+       fTransform = transform;
+
+       // NOTE: the transforms of earlier states are never expected to
+       // change, only the topmost state ever changes
+       if (fPreviousState != NULL)
+               fCombinedTransform = fPreviousState->fCombinedTransform * 
fTransform;
+       else
+               fCombinedTransform = fTransform;
 }
 
 
@@ -430,12 +457,26 @@ DrawState::Transform(float* x, float* y) const
        *y *= fCombinedScale;
        *x += fCombinedOrigin.x;
        *y += fCombinedOrigin.y;
+       if (!fCombinedTransform.IsIdentity()) {
+               double _x = *x;
+               double _y = *y;
+               fCombinedTransform.Apply(&_x, &_y);
+               *x = _x;
+               *y = _y;
+       }
 }
 
 
 void
 DrawState::InverseTransform(float* x, float* y) const
 {
+       if (!fCombinedTransform.IsIdentity()) {
+               double _x = *x;
+               double _y = *y;
+               fCombinedTransform.ApplyInverse(&_x, &_y);
+               *x = _x;
+               *y = _y;
+       }
        *x -= fCombinedOrigin.x;
        *y -= fCombinedOrigin.y;
        if (fCombinedScale != 0.0) {
@@ -667,6 +708,9 @@ DrawState::PrintToStream() const
 {
        printf("\t Origin: (%.1f, %.1f)\n", fOrigin.x, fOrigin.y);
        printf("\t Scale: %.2f\n", fScale);
+       printf("\t Transform: %.2f, %.2f, %.2f, %.2f, %.2f, %.2f\n",
+               fTransform.sx, fTransform.shy, fTransform.shx,
+               fTransform.sy, fTransform.tx, fTransform.ty);
 
        printf("\t Pen Location and Size: (%.1f, %.1f) - %.2f (%.2f)\n",
                   fPenLocation.x, fPenLocation.y, PenSize(), fPenSize);
diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h
index 792257e..58ca037 100644
--- a/src/servers/app/DrawState.h
+++ b/src/servers/app/DrawState.h
@@ -12,10 +12,11 @@
 #define _DRAW_STATE_H_
 
 
+#include <AffineTransform.h>
 #include <GraphicsDefs.h>
 #include <InterfaceDefs.h>
 #include <Point.h>
-#include <View.h> // for B_FONT_ALL
+#include <View.h>
 
 #include "ServerFont.h"
 #include "PatternHandler.h"
@@ -60,6 +61,12 @@ public:
                float                           CombinedScale() const
                                                                { return 
fCombinedScale; }
 
+               void                            SetTransform(BAffineTransform 
transform);
+               BAffineTransform        Transform() const
+                                                               { return 
fTransform; }
+               BAffineTransform        CombinedTransform() const
+                                                               { return 
fCombinedTransform; }
+
                                                        // additional clipping 
as requested by client
                void                            SetClippingRegion(const 
BRegion* region);
 
@@ -149,6 +156,8 @@ protected:
                BPoint                          fCombinedOrigin;
                float                           fScale;
                float                           fCombinedScale;
+               BAffineTransform        fTransform;
+               BAffineTransform        fCombinedTransform;
 
                BRegion*                        fClippingRegion;
 
diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp
index 1083673..c308149 100644
--- a/src/servers/app/ServerWindow.cpp
+++ b/src/servers/app/ServerWindow.cpp
@@ -1575,6 +1575,36 @@ fDesktop->LockSingleWindow();
                        fLink.Flush();
                        break;
                }
+               case AS_VIEW_SET_TRANSFORM:
+               {
+                       BAffineTransform transform;
+                       if (link.Read<BAffineTransform>(&transform) != B_OK)
+                               break;
+
+                       DTRACE(("ServerWindow %s: Message 
AS_VIEW_SET_TRANSFORM: "
+                               "View: %s -> transform: %.2f, %.2f, %.2f, %.2f, 
%.2f, %.2f\n",
+                               Title(), fCurrentView->Name(), transform.sx, 
transform.shy,
+                               transform.shx, transform.sy, transform.tx, 
transform.ty));
+
+                       fCurrentView->CurrentState()->SetTransform(transform);
+                       _UpdateDrawState(fCurrentView);
+                       break;
+               }
+               case AS_VIEW_GET_TRANSFORM:
+               {
+                       BAffineTransform transform
+                               = fCurrentView->CurrentState()->Transform();
+
+                       DTRACE(("ServerWindow %s: Message 
AS_VIEW_GET_TRANSFORM: "
+                               "View: %s -> transform: %.2f, %.2f, %.2f, %.2f, 
%.2f, %.2f\n",
+                               Title(), fCurrentView->Name(), transform.sx, 
transform.shy,
+                               transform.shx, transform.sy, transform.tx, 
transform.ty));
+
+                       fLink.StartMessage(B_OK);
+                       fLink.Attach<BAffineTransform>(transform);
+                       fLink.Flush();
+                       break;
+               }
                case AS_VIEW_SET_PEN_LOC:
                {
                        BPoint location;
@@ -2944,13 +2974,27 @@ ServerWindow::_DispatchPictureMessage(int32 code, 
BPrivate::LinkReceiver& link)
                case AS_VIEW_SET_SCALE:
                {
                        float scale;
-                       link.Read<float>(&scale);
+                       if (link.Read<float>(&scale) != B_OK)
+                               break;
+
                        picture->WriteSetScale(scale);
 
                        fCurrentView->SetScale(scale);
                        _UpdateDrawState(fCurrentView);
                        break;
                }
+               case AS_VIEW_SET_TRANSFORM:
+               {
+                       BAffineTransform transform;
+                       if (link.Read<BAffineTransform>(&transform) != B_OK)
+                               break;
+
+                       picture->WriteSetTransform(transform);
+
+                       fCurrentView->CurrentState()->SetTransform(transform);
+                       _UpdateDrawState(fCurrentView);
+                       break;
+               }
 
                case AS_VIEW_SET_PATTERN:
                {


Other related posts: