Icon-O-Matic: Add perspective transformations
As part of adding perspective transformations, agg_trans_perspective.h was patched to fix a multiple definitions error. This change has been submitted for review to the "upstream" repositories at [1], [2], and [3]. Also includes various other improvements such as VertexSource being split into its own file, code style improvements, and documentation improvements. [1] https://sourceforge.net/p/agg/patches/6/ [2] https://github.com/ghaerr/agg-2.6/pull/9 [3] https://github.com/aggeom/agg-2.6/pull/7 Change-Id: I4bffd2f87354bde10155e23145a232a925be6ff3 Reviewed-on: https://review.haiku-os.org/c/haiku/+/6801 Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
a1c86e7ada
commit
c6c2c04284
@@ -502,7 +502,7 @@ namespace agg
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
const trans_perspective&
|
inline const trans_perspective&
|
||||||
trans_perspective::multiply_inv(const trans_perspective& m)
|
trans_perspective::multiply_inv(const trans_perspective& m)
|
||||||
{
|
{
|
||||||
trans_perspective t = m;
|
trans_perspective t = m;
|
||||||
@@ -511,7 +511,7 @@ namespace agg
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
const trans_perspective&
|
inline const trans_perspective&
|
||||||
trans_perspective::multiply_inv(const trans_affine& m)
|
trans_perspective::multiply_inv(const trans_affine& m)
|
||||||
{
|
{
|
||||||
trans_affine t = m;
|
trans_affine t = m;
|
||||||
@@ -520,7 +520,7 @@ namespace agg
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
const trans_perspective&
|
inline const trans_perspective&
|
||||||
trans_perspective::premultiply_inv(const trans_perspective& m)
|
trans_perspective::premultiply_inv(const trans_perspective& m)
|
||||||
{
|
{
|
||||||
trans_perspective t = m;
|
trans_perspective t = m;
|
||||||
@@ -529,7 +529,7 @@ namespace agg
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
const trans_perspective&
|
inline const trans_perspective&
|
||||||
trans_perspective::premultiply_inv(const trans_affine& m)
|
trans_perspective::premultiply_inv(const trans_affine& m)
|
||||||
{
|
{
|
||||||
trans_perspective t(m);
|
trans_perspective t(m);
|
||||||
@@ -697,14 +697,14 @@ namespace agg
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
void trans_perspective::translation(double* dx, double* dy) const
|
inline void trans_perspective::translation(double* dx, double* dy) const
|
||||||
{
|
{
|
||||||
*dx = tx;
|
*dx = tx;
|
||||||
*dy = ty;
|
*dy = ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
void trans_perspective::scaling(double* x, double* y) const
|
inline void trans_perspective::scaling(double* x, double* y) const
|
||||||
{
|
{
|
||||||
double x1 = 0.0;
|
double x1 = 0.0;
|
||||||
double y1 = 0.0;
|
double y1 = 0.0;
|
||||||
@@ -719,7 +719,7 @@ namespace agg
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
void trans_perspective::scaling_abs(double* x, double* y) const
|
inline void trans_perspective::scaling_abs(double* x, double* y) const
|
||||||
{
|
{
|
||||||
*x = std::sqrt(sx * sx + shx * shx);
|
*x = std::sqrt(sx * sx + shx * shx);
|
||||||
*y = std::sqrt(shy * shy + sy * sy);
|
*y = std::sqrt(shy * shy + sy * sy);
|
||||||
|
|||||||
@@ -95,11 +95,12 @@ Application Icon-O-Matic :
|
|||||||
|
|
||||||
# icon/transformer
|
# icon/transformer
|
||||||
AffineTransformer.cpp
|
AffineTransformer.cpp
|
||||||
|
CompoundStyleTransformer.cpp
|
||||||
ContourTransformer.cpp
|
ContourTransformer.cpp
|
||||||
PathSource.cpp
|
PathSource.cpp
|
||||||
PerspectiveTransformer.cpp
|
PerspectiveTransformer.cpp
|
||||||
StrokeTransformer.cpp
|
StrokeTransformer.cpp
|
||||||
Transformer.cpp
|
StyleTransformer.cpp
|
||||||
TransformerFactory.cpp
|
TransformerFactory.cpp
|
||||||
|
|
||||||
# icon
|
# icon
|
||||||
@@ -275,6 +276,9 @@ Application Icon-O-Matic :
|
|||||||
# transformable
|
# transformable
|
||||||
CanvasTransformBox.cpp
|
CanvasTransformBox.cpp
|
||||||
ChannelTransform.cpp
|
ChannelTransform.cpp
|
||||||
|
PerspectiveBox.cpp
|
||||||
|
PerspectiveBoxStates.cpp
|
||||||
|
PerspectiveCommand.cpp
|
||||||
ResetTransformationCommand.cpp
|
ResetTransformationCommand.cpp
|
||||||
TransformBox.cpp
|
TransformBox.cpp
|
||||||
TransformBoxStates.cpp
|
TransformBoxStates.cpp
|
||||||
@@ -349,6 +353,7 @@ DoCatalogs Icon-O-Matic :
|
|||||||
RemoveStylesCommand.cpp
|
RemoveStylesCommand.cpp
|
||||||
SetColorCommand.cpp
|
SetColorCommand.cpp
|
||||||
SetGradientCommand.cpp
|
SetGradientCommand.cpp
|
||||||
|
PerspectiveCommand.cpp
|
||||||
ResetTransformationCommand.cpp
|
ResetTransformationCommand.cpp
|
||||||
TransformBoxStates.cpp
|
TransformBoxStates.cpp
|
||||||
TransformerFactory.cpp
|
TransformerFactory.cpp
|
||||||
|
|||||||
@@ -59,6 +59,8 @@
|
|||||||
#include "MessengerSaver.h"
|
#include "MessengerSaver.h"
|
||||||
#include "NativeSaver.h"
|
#include "NativeSaver.h"
|
||||||
#include "PathListView.h"
|
#include "PathListView.h"
|
||||||
|
#include "PerspectiveBox.h"
|
||||||
|
#include "PerspectiveTransformer.h"
|
||||||
#include "RDefExporter.h"
|
#include "RDefExporter.h"
|
||||||
#include "ScrollView.h"
|
#include "ScrollView.h"
|
||||||
#include "SimpleFileSaver.h"
|
#include "SimpleFileSaver.h"
|
||||||
@@ -105,6 +107,7 @@ enum {
|
|||||||
MSG_PATH_SELECTED = 'vpsl',
|
MSG_PATH_SELECTED = 'vpsl',
|
||||||
MSG_STYLE_SELECTED = 'stsl',
|
MSG_STYLE_SELECTED = 'stsl',
|
||||||
MSG_SHAPE_SELECTED = 'spsl',
|
MSG_SHAPE_SELECTED = 'spsl',
|
||||||
|
MSG_TRANSFORMER_SELECTED = 'trsl',
|
||||||
|
|
||||||
MSG_SHAPE_RESET_TRANSFORMATION = 'rtsh',
|
MSG_SHAPE_RESET_TRANSFORMATION = 'rtsh',
|
||||||
MSG_STYLE_RESET_TRANSFORMATION = 'rtst',
|
MSG_STYLE_RESET_TRANSFORMATION = 'rtst',
|
||||||
@@ -562,6 +565,20 @@ case MSG_SHAPE_SELECTED: {
|
|||||||
fState->AddManipulator(transformBox);
|
fState->AddManipulator(transformBox);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case MSG_TRANSFORMER_SELECTED: {
|
||||||
|
Transformer* transformer;
|
||||||
|
if (message->FindPointer("transformer", (void**)&transformer) < B_OK)
|
||||||
|
transformer = NULL;
|
||||||
|
|
||||||
|
fState->DeleteManipulators();
|
||||||
|
PerspectiveTransformer* perspectiveTransformer =
|
||||||
|
dynamic_cast<PerspectiveTransformer*>(transformer);
|
||||||
|
if (perspectiveTransformer != NULL) {
|
||||||
|
PerspectiveBox* transformBox = new (nothrow) PerspectiveBox(
|
||||||
|
fCanvasView, perspectiveTransformer);
|
||||||
|
fState->AddManipulator(transformBox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case MSG_RENAME_OBJECT:
|
case MSG_RENAME_OBJECT:
|
||||||
fPropertyListView->FocusNameProperty();
|
fPropertyListView->FocusNameProperty();
|
||||||
@@ -1087,7 +1104,7 @@ MainWindow::_CreateGUI()
|
|||||||
fShapeListView = new ShapeListView(BRect(0, 0, splitWidth, 100),
|
fShapeListView = new ShapeListView(BRect(0, 0, splitWidth, 100),
|
||||||
"shape list view", new BMessage(MSG_SHAPE_SELECTED), this);
|
"shape list view", new BMessage(MSG_SHAPE_SELECTED), this);
|
||||||
fTransformerListView = new TransformerListView(BRect(0, 0, splitWidth, 100),
|
fTransformerListView = new TransformerListView(BRect(0, 0, splitWidth, 100),
|
||||||
"transformer list view");
|
"transformer list view", new BMessage(MSG_TRANSFORMER_SELECTED), this);
|
||||||
fPropertyListView = new IconObjectListView();
|
fPropertyListView = new IconObjectListView();
|
||||||
|
|
||||||
BLayoutBuilder::Split<>(leftSideView)
|
BLayoutBuilder::Split<>(leftSideView)
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ class IconObject : public Observable,
|
|||||||
const char* Name() const
|
const char* Name() const
|
||||||
{ return fName.String(); }
|
{ return fName.String(); }
|
||||||
|
|
||||||
|
// TODO: let IconObject control its own manipulators?
|
||||||
|
// This would allow VectorPaths to control their own PathManipulator,
|
||||||
|
// Styles to control their own TransformGradientBox, etc.
|
||||||
private:
|
private:
|
||||||
BString fName;
|
BString fName;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -201,8 +201,7 @@ TransformerListView::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
Transformer* transformer
|
Transformer* transformer
|
||||||
= TransformerFactory::TransformerFor(type,
|
= TransformerFactory::TransformerFor(type, fShape->VertexSource(), fShape);
|
||||||
fShape->VertexSource());
|
|
||||||
if (!transformer)
|
if (!transformer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -396,9 +395,9 @@ TransformerListView::SetMenu(BMenu* menu)
|
|||||||
message->AddInt32("type", STROKE_TRANSFORMER);
|
message->AddInt32("type", STROKE_TRANSFORMER);
|
||||||
fStrokeMI = new BMenuItem(B_TRANSLATE("Stroke"), message);
|
fStrokeMI = new BMenuItem(B_TRANSLATE("Stroke"), message);
|
||||||
|
|
||||||
// message = new BMessage(MSG_ADD_TRANSFORMER);
|
message = new BMessage(MSG_ADD_TRANSFORMER);
|
||||||
// message->AddInt32("type", PERSPECTIVE_TRANSFORMER);
|
message->AddInt32("type", PERSPECTIVE_TRANSFORMER);
|
||||||
// fPerspectiveMI = new BMenuItem(B_TRANSLATE("Perspective"), message);
|
fPerspectiveMI = new BMenuItem(B_TRANSLATE("Perspective"), message);
|
||||||
|
|
||||||
// message = new BMessage(MSG_ADD_TRANSFORMER);
|
// message = new BMessage(MSG_ADD_TRANSFORMER);
|
||||||
// message->AddInt32("type", AFFINE_TRANSFORMER);
|
// message->AddInt32("type", AFFINE_TRANSFORMER);
|
||||||
@@ -408,6 +407,7 @@ TransformerListView::SetMenu(BMenu* menu)
|
|||||||
|
|
||||||
addMenu->AddItem(fContourMI);
|
addMenu->AddItem(fContourMI);
|
||||||
addMenu->AddItem(fStrokeMI);
|
addMenu->AddItem(fStrokeMI);
|
||||||
|
addMenu->AddItem(fPerspectiveMI);
|
||||||
|
|
||||||
addMenu->SetTargetForItems(this);
|
addMenu->SetTargetForItems(this);
|
||||||
fMenu->AddItem(addMenu);
|
fMenu->AddItem(addMenu);
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ class TransformerListView : public SimpleListView,
|
|||||||
BMenu* fMenu;
|
BMenu* fMenu;
|
||||||
BMenuItem* fContourMI;
|
BMenuItem* fContourMI;
|
||||||
BMenuItem* fStrokeMI;
|
BMenuItem* fStrokeMI;
|
||||||
|
BMenuItem* fPerspectiveMI;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRANSFORMER_LIST_VIEW_H
|
#endif // TRANSFORMER_LIST_VIEW_H
|
||||||
|
|||||||
@@ -483,11 +483,17 @@ _WriteTransformer(LittleEndianBuffer& buffer, Transformer* t)
|
|||||||
|| !buffer.Write(miterLimit))
|
|| !buffer.Write(miterLimit))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
} else if (dynamic_cast<PerspectiveTransformer*>(t)) {
|
} else if (PerspectiveTransformer* perspective
|
||||||
|
= dynamic_cast<PerspectiveTransformer*>(t)) {
|
||||||
// perspective
|
// perspective
|
||||||
if (!buffer.Write((uint8)TRANSFORMER_TYPE_PERSPECTIVE))
|
if (!buffer.Write((uint8)TRANSFORMER_TYPE_PERSPECTIVE))
|
||||||
return false;
|
return false;
|
||||||
// TODO: ... (upgrade AGG for storage support of trans_perspective)
|
double matrix[9];
|
||||||
|
perspective->store_to(matrix);
|
||||||
|
for (int32 i = 0; i < 9; i++) {
|
||||||
|
if (!write_float_24(buffer, (float)matrix[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (StrokeTransformer* stroke
|
} else if (StrokeTransformer* stroke
|
||||||
= dynamic_cast<StrokeTransformer*>(t)) {
|
= dynamic_cast<StrokeTransformer*>(t)) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ struct style_map {
|
|||||||
|
|
||||||
/*! Turns text into its associated paths and shapes.
|
/*! Turns text into its associated paths and shapes.
|
||||||
Coloring can also be imported from applications, such as StyledEdit, that
|
Coloring can also be imported from applications, such as StyledEdit, that
|
||||||
specify it.
|
specify it in a supported format.
|
||||||
*/
|
*/
|
||||||
class StyledTextImporter : public Importer {
|
class StyledTextImporter : public Importer {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -0,0 +1,449 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2009, 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PerspectiveBox.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <agg_trans_affine.h>
|
||||||
|
#include <agg_math.h>
|
||||||
|
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
#include "CanvasView.h"
|
||||||
|
#include "StateView.h"
|
||||||
|
#include "support.h"
|
||||||
|
#include "PerspectiveBoxStates.h"
|
||||||
|
#include "PerspectiveCommand.h"
|
||||||
|
#include "PerspectiveTransformer.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define INSET 8.0
|
||||||
|
|
||||||
|
|
||||||
|
using std::nothrow;
|
||||||
|
using namespace PerspectiveBoxStates;
|
||||||
|
|
||||||
|
|
||||||
|
PerspectiveBox::PerspectiveBox(CanvasView* view,
|
||||||
|
PerspectiveTransformer* parent)
|
||||||
|
:
|
||||||
|
Manipulator(NULL),
|
||||||
|
|
||||||
|
fLeftTop(parent->LeftTop()),
|
||||||
|
fRightTop(parent->RightTop()),
|
||||||
|
fLeftBottom(parent->LeftBottom()),
|
||||||
|
fRightBottom(parent->RightBottom()),
|
||||||
|
|
||||||
|
fCurrentCommand(NULL),
|
||||||
|
fCurrentState(NULL),
|
||||||
|
|
||||||
|
fDragging(false),
|
||||||
|
fMousePos(-10000.0, -10000.0),
|
||||||
|
fModifiers(0),
|
||||||
|
|
||||||
|
fPreviousBox(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN),
|
||||||
|
|
||||||
|
fCanvasView(view),
|
||||||
|
fPerspective(parent),
|
||||||
|
|
||||||
|
fDragLTState(new DragCornerState(this, &fLeftTop)),
|
||||||
|
fDragRTState(new DragCornerState(this, &fRightTop)),
|
||||||
|
fDragLBState(new DragCornerState(this, &fLeftBottom)),
|
||||||
|
fDragRBState(new DragCornerState(this, &fRightBottom))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PerspectiveBox::~PerspectiveBox()
|
||||||
|
{
|
||||||
|
_NotifyDeleted();
|
||||||
|
|
||||||
|
delete fCurrentCommand;
|
||||||
|
delete fDragLTState;
|
||||||
|
delete fDragRTState;
|
||||||
|
delete fDragLBState;
|
||||||
|
delete fDragRBState;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::Draw(BView* into, BRect updateRect)
|
||||||
|
{
|
||||||
|
// convert to canvas view coordinates
|
||||||
|
BPoint lt = fLeftTop;
|
||||||
|
BPoint rt = fRightTop;
|
||||||
|
BPoint lb = fLeftBottom;
|
||||||
|
BPoint rb = fRightBottom;
|
||||||
|
|
||||||
|
fCanvasView->ConvertFromCanvas(<);
|
||||||
|
fCanvasView->ConvertFromCanvas(&rt);
|
||||||
|
fCanvasView->ConvertFromCanvas(&lb);
|
||||||
|
fCanvasView->ConvertFromCanvas(&rb);
|
||||||
|
|
||||||
|
into->SetDrawingMode(B_OP_COPY);
|
||||||
|
into->SetHighColor(255, 255, 255, 255);
|
||||||
|
into->SetLowColor(0, 0, 0, 255);
|
||||||
|
|
||||||
|
_StrokeBWLine(into, lt, rt);
|
||||||
|
_StrokeBWLine(into, rt, rb);
|
||||||
|
_StrokeBWLine(into, rb, lb);
|
||||||
|
_StrokeBWLine(into, lb, lt);
|
||||||
|
|
||||||
|
_StrokeBWPoint(into, lt, 0.0);
|
||||||
|
_StrokeBWPoint(into, rt, 90.0);
|
||||||
|
_StrokeBWPoint(into, rb, 180.0);
|
||||||
|
_StrokeBWPoint(into, lb, 270.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PerspectiveBox::MouseDown(BPoint where)
|
||||||
|
{
|
||||||
|
fCanvasView->FilterMouse(&where);
|
||||||
|
fCanvasView->ConvertToCanvas(&where);
|
||||||
|
|
||||||
|
fDragging = true;
|
||||||
|
if (fCurrentState) {
|
||||||
|
fCurrentState->SetOrigin(where);
|
||||||
|
|
||||||
|
delete fCurrentCommand;
|
||||||
|
fCurrentCommand = new (nothrow) PerspectiveCommand(this, fPerspective,
|
||||||
|
fPerspective->LeftTop(), fPerspective->RightTop(),
|
||||||
|
fPerspective->LeftBottom(), fPerspective->RightBottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::MouseMoved(BPoint where)
|
||||||
|
{
|
||||||
|
fCanvasView->FilterMouse(&where);
|
||||||
|
fCanvasView->ConvertToCanvas(&where);
|
||||||
|
|
||||||
|
if (fMousePos != where) {
|
||||||
|
fMousePos = where;
|
||||||
|
if (fCurrentState) {
|
||||||
|
fCurrentState->DragTo(fMousePos, fModifiers);
|
||||||
|
fCurrentState->UpdateViewCursor(fCanvasView, fMousePos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Command*
|
||||||
|
PerspectiveBox::MouseUp()
|
||||||
|
{
|
||||||
|
fDragging = false;
|
||||||
|
return FinishTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PerspectiveBox::MouseOver(BPoint where)
|
||||||
|
{
|
||||||
|
fCanvasView->ConvertToCanvas(&where);
|
||||||
|
|
||||||
|
fMousePos = where;
|
||||||
|
fCurrentState = _DragStateFor(where, fCanvasView->ZoomLevel());
|
||||||
|
|
||||||
|
if (fCurrentState) {
|
||||||
|
fCurrentState->UpdateViewCursor(fCanvasView, fMousePos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
BRect
|
||||||
|
PerspectiveBox::Bounds()
|
||||||
|
{
|
||||||
|
// convert from canvas view coordinates
|
||||||
|
BPoint lt = fLeftTop;
|
||||||
|
BPoint rt = fRightTop;
|
||||||
|
BPoint lb = fLeftBottom;
|
||||||
|
BPoint rb = fRightBottom;
|
||||||
|
|
||||||
|
fCanvasView->ConvertFromCanvas(<);
|
||||||
|
fCanvasView->ConvertFromCanvas(&rt);
|
||||||
|
fCanvasView->ConvertFromCanvas(&lb);
|
||||||
|
fCanvasView->ConvertFromCanvas(&rb);
|
||||||
|
|
||||||
|
BRect bounds;
|
||||||
|
bounds.left = min4(lt.x, rt.x, lb.x, rb.x);
|
||||||
|
bounds.top = min4(lt.y, rt.y, lb.y, rb.y);
|
||||||
|
bounds.right = max4(lt.x, rt.x, lb.x, rb.x);
|
||||||
|
bounds.bottom = max4(lt.y, rt.y, lb.y, rb.y);
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BRect
|
||||||
|
PerspectiveBox::TrackingBounds(BView* withinView)
|
||||||
|
{
|
||||||
|
return withinView->Bounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::ModifiersChanged(uint32 modifiers)
|
||||||
|
{
|
||||||
|
fModifiers = modifiers;
|
||||||
|
if (fDragging && fCurrentState) {
|
||||||
|
fCurrentState->DragTo(fMousePos, fModifiers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PerspectiveBox::UpdateCursor()
|
||||||
|
{
|
||||||
|
if (fCurrentState) {
|
||||||
|
fCurrentState->UpdateViewCursor(fCanvasView, fMousePos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::AttachedToView(BView* view)
|
||||||
|
{
|
||||||
|
view->Invalidate(Bounds().InsetByCopy(-INSET, -INSET));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::DetachedFromView(BView* view)
|
||||||
|
{
|
||||||
|
view->Invalidate(Bounds().InsetByCopy(-INSET, -INSET));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::ObjectChanged(const Observable* object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::TransformTo(
|
||||||
|
BPoint leftTop, BPoint rightTop, BPoint leftBottom, BPoint rightBottom)
|
||||||
|
{
|
||||||
|
if (fLeftTop == leftTop
|
||||||
|
&& fRightTop == rightTop
|
||||||
|
&& fLeftBottom == leftBottom
|
||||||
|
&& fRightBottom == rightBottom)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fLeftTop = leftTop;
|
||||||
|
fRightTop = rightTop;
|
||||||
|
fLeftBottom = leftBottom;
|
||||||
|
fRightBottom = rightBottom;
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::Update(bool deep)
|
||||||
|
{
|
||||||
|
BRect r = Bounds();
|
||||||
|
BRect dirty(r | fPreviousBox);
|
||||||
|
dirty.InsetBy(-INSET, -INSET);
|
||||||
|
fCanvasView->Invalidate(dirty);
|
||||||
|
fPreviousBox = r;
|
||||||
|
|
||||||
|
if (deep)
|
||||||
|
fPerspective->TransformTo(fLeftTop, fRightTop, fLeftBottom, fRightBottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Command*
|
||||||
|
PerspectiveBox::FinishTransaction()
|
||||||
|
{
|
||||||
|
Command* command = fCurrentCommand;
|
||||||
|
if (fCurrentCommand) {
|
||||||
|
fCurrentCommand->SetNewPerspective(
|
||||||
|
fPerspective->LeftTop(), fPerspective->RightTop(),
|
||||||
|
fPerspective->LeftBottom(), fPerspective->RightBottom());
|
||||||
|
fCurrentCommand = NULL;
|
||||||
|
}
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PerspectiveBox::AddListener(PerspectiveBoxListener* listener)
|
||||||
|
{
|
||||||
|
if (listener && !fListeners.HasItem((void*)listener))
|
||||||
|
return fListeners.AddItem((void*)listener);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PerspectiveBox::RemoveListener(PerspectiveBoxListener* listener)
|
||||||
|
{
|
||||||
|
return fListeners.RemoveItem((void*)listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::_NotifyDeleted() const
|
||||||
|
{
|
||||||
|
BList listeners(fListeners);
|
||||||
|
int32 count = listeners.CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
PerspectiveBoxListener* listener
|
||||||
|
= (PerspectiveBoxListener*)listeners.ItemAtFast(i);
|
||||||
|
listener->PerspectiveBoxDeleted(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! where is expected in canvas view coordinates
|
||||||
|
DragState*
|
||||||
|
PerspectiveBox::_DragStateFor(BPoint where, float canvasZoom)
|
||||||
|
{
|
||||||
|
DragState* state = NULL;
|
||||||
|
|
||||||
|
// convert to canvas zoom level
|
||||||
|
//
|
||||||
|
// the conversion is necessary, because the "hot regions"
|
||||||
|
// around a point should be the same size no matter what
|
||||||
|
// zoom level the canvas is displayed at
|
||||||
|
float inset = INSET / canvasZoom;
|
||||||
|
|
||||||
|
// check if the cursor is over the corners
|
||||||
|
float dLT = point_point_distance(fLeftTop, where);
|
||||||
|
float dRT = point_point_distance(fRightTop, where);
|
||||||
|
float dLB = point_point_distance(fLeftBottom, where);
|
||||||
|
float dRB = point_point_distance(fRightBottom, where);
|
||||||
|
float d = min4(dLT, dRT, dLB, dRB);
|
||||||
|
if (d < inset) {
|
||||||
|
if (d == dLT)
|
||||||
|
state = fDragLTState;
|
||||||
|
else if (d == dRT)
|
||||||
|
state = fDragRTState;
|
||||||
|
else if (d == dLB)
|
||||||
|
state = fDragLBState;
|
||||||
|
else if (d == dRB)
|
||||||
|
state = fDragRBState;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::_StrokeBWLine(BView* into, BPoint from, BPoint to) const
|
||||||
|
{
|
||||||
|
// find out how to offset the second line optimally
|
||||||
|
BPoint offset(0.0, 0.0);
|
||||||
|
// first, do we have a more horizontal line or a more vertical line?
|
||||||
|
float xDiff = to.x - from.x;
|
||||||
|
float yDiff = to.y - from.y;
|
||||||
|
if (fabs(xDiff) > fabs(yDiff)) {
|
||||||
|
// horizontal
|
||||||
|
if (xDiff > 0.0) {
|
||||||
|
offset.y = -1.0;
|
||||||
|
} else {
|
||||||
|
offset.y = 1.0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// vertical
|
||||||
|
if (yDiff < 0.0) {
|
||||||
|
offset.x = -1.0;
|
||||||
|
} else {
|
||||||
|
offset.x = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// stroke two lines in high and low color of the view
|
||||||
|
into->StrokeLine(from, to, B_SOLID_LOW);
|
||||||
|
from += offset;
|
||||||
|
to += offset;
|
||||||
|
into->StrokeLine(from, to, B_SOLID_HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveBox::_StrokeBWPoint(BView* into, BPoint point, double angle) const
|
||||||
|
{
|
||||||
|
double x = point.x;
|
||||||
|
double y = point.y;
|
||||||
|
|
||||||
|
double x1 = x;
|
||||||
|
double y1 = y - 5.0;
|
||||||
|
|
||||||
|
double x2 = x - 5.0;
|
||||||
|
double y2 = y - 5.0;
|
||||||
|
|
||||||
|
double x3 = x - 5.0;
|
||||||
|
double y3 = y;
|
||||||
|
|
||||||
|
agg::trans_affine m;
|
||||||
|
|
||||||
|
double xOffset = -x;
|
||||||
|
double yOffset = -y;
|
||||||
|
|
||||||
|
agg::trans_affine_rotation r(angle * M_PI / 180.0);
|
||||||
|
|
||||||
|
r.transform(&xOffset, &yOffset);
|
||||||
|
xOffset = x + xOffset;
|
||||||
|
yOffset = y + yOffset;
|
||||||
|
|
||||||
|
m.multiply(r);
|
||||||
|
m.multiply(agg::trans_affine_translation(xOffset, yOffset));
|
||||||
|
|
||||||
|
m.transform(&x, &y);
|
||||||
|
m.transform(&x1, &y1);
|
||||||
|
m.transform(&x2, &y2);
|
||||||
|
m.transform(&x3, &y3);
|
||||||
|
|
||||||
|
BPoint p[4];
|
||||||
|
p[0] = BPoint(x, y);
|
||||||
|
p[1] = BPoint(x1, y1);
|
||||||
|
p[2] = BPoint(x2, y2);
|
||||||
|
p[3] = BPoint(x3, y3);
|
||||||
|
|
||||||
|
into->FillPolygon(p, 4, B_SOLID_HIGH);
|
||||||
|
|
||||||
|
into->StrokeLine(p[0], p[1], B_SOLID_LOW);
|
||||||
|
into->StrokeLine(p[1], p[2], B_SOLID_LOW);
|
||||||
|
into->StrokeLine(p[2], p[3], B_SOLID_LOW);
|
||||||
|
into->StrokeLine(p[3], p[0], B_SOLID_LOW);
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2007, 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
#ifndef PERSPECTIVE_BOX_H
|
||||||
|
#define PERSPECTIVE_BOX_H
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
#include <Point.h>
|
||||||
|
#include <Referenceable.h>
|
||||||
|
|
||||||
|
#include "Manipulator.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace PerspectiveBoxStates {
|
||||||
|
class DragState;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CanvasView;
|
||||||
|
class Command;
|
||||||
|
class PerspectiveCommand;
|
||||||
|
class PerspectiveBox;
|
||||||
|
class PerspectiveTransformer;
|
||||||
|
|
||||||
|
|
||||||
|
class PerspectiveBoxListener {
|
||||||
|
public:
|
||||||
|
PerspectiveBoxListener() {}
|
||||||
|
virtual ~PerspectiveBoxListener() {}
|
||||||
|
|
||||||
|
virtual void PerspectiveBoxDeleted(
|
||||||
|
const PerspectiveBox* box) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PerspectiveBox : public Manipulator {
|
||||||
|
public:
|
||||||
|
PerspectiveBox(CanvasView* view,
|
||||||
|
PerspectiveTransformer* parent);
|
||||||
|
virtual ~PerspectiveBox();
|
||||||
|
|
||||||
|
// Manipulator interface
|
||||||
|
virtual void Draw(BView* into, BRect updateRect);
|
||||||
|
|
||||||
|
virtual bool MouseDown(BPoint where);
|
||||||
|
virtual void MouseMoved(BPoint where);
|
||||||
|
virtual Command* MouseUp();
|
||||||
|
virtual bool MouseOver(BPoint where);
|
||||||
|
|
||||||
|
virtual BRect Bounds();
|
||||||
|
virtual BRect TrackingBounds(BView* withinView);
|
||||||
|
|
||||||
|
virtual void ModifiersChanged(uint32 modifiers);
|
||||||
|
|
||||||
|
virtual bool UpdateCursor();
|
||||||
|
|
||||||
|
virtual void AttachedToView(BView* view);
|
||||||
|
virtual void DetachedFromView(BView* view);
|
||||||
|
|
||||||
|
// Observer interface
|
||||||
|
virtual void ObjectChanged(const Observable* object);
|
||||||
|
|
||||||
|
// PerspectiveTransformBox
|
||||||
|
void TransformTo(BPoint leftTop, BPoint rightTop,
|
||||||
|
BPoint leftBottom, BPoint rightBottom);
|
||||||
|
|
||||||
|
virtual void Update(bool deep = true);
|
||||||
|
|
||||||
|
Command* FinishTransaction();
|
||||||
|
|
||||||
|
// Listener support
|
||||||
|
bool AddListener(PerspectiveBoxListener* listener);
|
||||||
|
bool RemoveListener(PerspectiveBoxListener* listener);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _NotifyDeleted() const;
|
||||||
|
PerspectiveBoxStates::DragState* _DragStateFor(
|
||||||
|
BPoint canvasWhere, float canvasZoom);
|
||||||
|
void _StrokeBWLine(BView* into,
|
||||||
|
BPoint from, BPoint to) const;
|
||||||
|
void _StrokeBWPoint(BView* into,
|
||||||
|
BPoint point, double angle) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BPoint fLeftTop;
|
||||||
|
BPoint fRightTop;
|
||||||
|
BPoint fLeftBottom;
|
||||||
|
BPoint fRightBottom;
|
||||||
|
|
||||||
|
PerspectiveCommand* fCurrentCommand;
|
||||||
|
PerspectiveBoxStates::DragState* fCurrentState;
|
||||||
|
|
||||||
|
bool fDragging;
|
||||||
|
BPoint fMousePos;
|
||||||
|
uint32 fModifiers;
|
||||||
|
|
||||||
|
BList fListeners;
|
||||||
|
|
||||||
|
BRect fPreviousBox;
|
||||||
|
|
||||||
|
// "static" state objects
|
||||||
|
CanvasView* fCanvasView;
|
||||||
|
BReference<PerspectiveTransformer> fPerspective;
|
||||||
|
|
||||||
|
PerspectiveBoxStates::DragState* fDragLTState;
|
||||||
|
PerspectiveBoxStates::DragState* fDragRTState;
|
||||||
|
PerspectiveBoxStates::DragState* fDragLBState;
|
||||||
|
PerspectiveBoxStates::DragState* fDragRBState;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PERSPECTIVE_BOX_H
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2009, 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PerspectiveBoxStates.h"
|
||||||
|
|
||||||
|
#include <Cursor.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
#include "cursors.h"
|
||||||
|
#include "PerspectiveBox.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace PerspectiveBoxStates;
|
||||||
|
|
||||||
|
|
||||||
|
DragState::DragState(PerspectiveBox* parent)
|
||||||
|
:
|
||||||
|
fOrigin(0.0, 0.0),
|
||||||
|
fParent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DragState::_SetViewCursor(BView* view, const uchar* cursorData) const
|
||||||
|
{
|
||||||
|
BCursor cursor(cursorData);
|
||||||
|
view->SetViewCursor(&cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - DragCornerState
|
||||||
|
|
||||||
|
|
||||||
|
DragCornerState::DragCornerState(PerspectiveBox* parent, BPoint* point)
|
||||||
|
:
|
||||||
|
DragState(parent),
|
||||||
|
fPoint(point)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DragCornerState::SetOrigin(BPoint origin)
|
||||||
|
{
|
||||||
|
DragState::SetOrigin(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DragCornerState::DragTo(BPoint current, uint32 modifiers)
|
||||||
|
{
|
||||||
|
*fPoint = current;
|
||||||
|
fParent->Update(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DragCornerState::UpdateViewCursor(BView* view, BPoint current) const
|
||||||
|
{
|
||||||
|
_SetViewCursor(view, kPathMoveCursor);
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
#ifndef PERSPECTIVE_BOX_STATES_H
|
||||||
|
#define PERSPECTIVE_BOX_STATES_H
|
||||||
|
|
||||||
|
#include <Point.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BView;
|
||||||
|
class PerspectiveBox;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PerspectiveBoxStates {
|
||||||
|
|
||||||
|
class DragState {
|
||||||
|
public:
|
||||||
|
DragState(PerspectiveBox* parent);
|
||||||
|
virtual ~DragState() {}
|
||||||
|
|
||||||
|
virtual void SetOrigin(BPoint origin)
|
||||||
|
{ fOrigin = origin; }
|
||||||
|
virtual void DragTo(BPoint current, uint32 modifiers) = 0;
|
||||||
|
virtual void UpdateViewCursor(BView* view, BPoint current) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _SetViewCursor(BView* view,
|
||||||
|
const uchar* cursorData) const;
|
||||||
|
|
||||||
|
BPoint fOrigin;
|
||||||
|
PerspectiveBox* fParent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DragCornerState : public DragState {
|
||||||
|
public:
|
||||||
|
DragCornerState(
|
||||||
|
PerspectiveBox* parent, BPoint* point);
|
||||||
|
virtual ~DragCornerState() {}
|
||||||
|
|
||||||
|
virtual void SetOrigin(BPoint origin);
|
||||||
|
virtual void DragTo(BPoint current, uint32 modifiers);
|
||||||
|
virtual void UpdateViewCursor(BView* view, BPoint current) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BPoint* fPoint;
|
||||||
|
|
||||||
|
BPoint fOldOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // PerspectiveBoxStates namespace
|
||||||
|
|
||||||
|
#endif // PERSPECTIVE_BOX_STATES_H
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2010, Stephan Aßmus <superstippi@gmx.de>.
|
||||||
|
* Copyright 2006-2009, 2023, Haiku.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "PerspectiveCommand.h"
|
||||||
|
|
||||||
|
#include <Catalog.h>
|
||||||
|
#include <Locale.h>
|
||||||
|
|
||||||
|
#include "PerspectiveTransformer.h"
|
||||||
|
|
||||||
|
|
||||||
|
#undef B_TRANSLATION_CONTEXT
|
||||||
|
#define B_TRANSLATION_CONTEXT "Icon-O-Matic-PerspectiveCommand"
|
||||||
|
|
||||||
|
|
||||||
|
PerspectiveCommand::PerspectiveCommand(PerspectiveBox* box,
|
||||||
|
PerspectiveTransformer* transformer, BPoint leftTop, BPoint rightTop
|
||||||
|
, BPoint leftBottom, BPoint rightBottom)
|
||||||
|
: fTransformBox(box),
|
||||||
|
fTransformer(transformer),
|
||||||
|
fOldLeftTop(leftTop),
|
||||||
|
fOldRightTop(rightTop),
|
||||||
|
fOldLeftBottom(leftBottom),
|
||||||
|
fOldRightBottom(rightBottom),
|
||||||
|
fNewLeftTop(leftTop),
|
||||||
|
fNewRightTop(rightTop),
|
||||||
|
fNewLeftBottom(leftBottom),
|
||||||
|
fNewRightBottom(rightBottom)
|
||||||
|
{
|
||||||
|
if (fTransformer == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fTransformer->AcquireReference();
|
||||||
|
|
||||||
|
if (fTransformBox != NULL)
|
||||||
|
fTransformBox->AddListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PerspectiveCommand::~PerspectiveCommand()
|
||||||
|
{
|
||||||
|
if (fTransformer != NULL)
|
||||||
|
fTransformer->ReleaseReference();
|
||||||
|
|
||||||
|
if (fTransformBox != NULL)
|
||||||
|
fTransformBox->RemoveListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PerspectiveCommand::InitCheck()
|
||||||
|
{
|
||||||
|
if (fTransformer != NULL
|
||||||
|
&& (fOldLeftTop != fNewLeftTop
|
||||||
|
|| fOldRightTop != fNewRightTop
|
||||||
|
|| fOldLeftBottom != fNewLeftBottom
|
||||||
|
|| fOldRightBottom != fNewRightBottom))
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
return B_NO_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PerspectiveCommand::Perform()
|
||||||
|
{
|
||||||
|
// objects are already transformed
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PerspectiveCommand::Undo()
|
||||||
|
{
|
||||||
|
if (fTransformBox != NULL) {
|
||||||
|
fTransformBox->TransformTo(fOldLeftTop, fOldRightTop, fOldLeftBottom, fOldRightBottom);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
fTransformer->TransformTo(fOldLeftTop, fOldRightTop, fOldLeftBottom, fOldRightBottom);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PerspectiveCommand::Redo()
|
||||||
|
{
|
||||||
|
if (fTransformBox != NULL) {
|
||||||
|
fTransformBox->TransformTo(fNewLeftTop, fNewRightTop, fNewLeftBottom, fNewRightBottom);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
fTransformer->TransformTo(fNewLeftTop, fNewRightTop, fNewLeftBottom, fNewRightBottom);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveCommand::GetName(BString& name)
|
||||||
|
{
|
||||||
|
name << B_TRANSLATE("Change perspective");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveCommand::PerspectiveBoxDeleted(const PerspectiveBox* box)
|
||||||
|
{
|
||||||
|
if (fTransformBox == box) {
|
||||||
|
if (fTransformBox != NULL)
|
||||||
|
fTransformBox->RemoveListener(this);
|
||||||
|
fTransformBox = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveCommand::SetNewPerspective(
|
||||||
|
BPoint leftTop, BPoint rightTop, BPoint leftBottom, BPoint rightBottom)
|
||||||
|
{
|
||||||
|
fNewLeftTop = leftTop;
|
||||||
|
fNewRightTop = rightTop;
|
||||||
|
fNewLeftBottom = leftBottom;
|
||||||
|
fNewRightBottom = rightBottom;
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PERSPECTIVE_COMMAND_H
|
||||||
|
#define PERSPECTIVE_COMMAND_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Point.h>
|
||||||
|
|
||||||
|
#include "Command.h"
|
||||||
|
#include "PerspectiveBox.h"
|
||||||
|
|
||||||
|
|
||||||
|
class PerspectiveTransformer;
|
||||||
|
|
||||||
|
|
||||||
|
class PerspectiveCommand : public Command, public PerspectiveBoxListener {
|
||||||
|
public:
|
||||||
|
PerspectiveCommand(PerspectiveBox* box,
|
||||||
|
PerspectiveTransformer* transformer,
|
||||||
|
BPoint leftTop, BPoint rightTop,
|
||||||
|
BPoint leftBottom, BPoint rightBottom);
|
||||||
|
virtual ~PerspectiveCommand();
|
||||||
|
|
||||||
|
// Command interface
|
||||||
|
virtual status_t InitCheck();
|
||||||
|
|
||||||
|
virtual status_t Perform();
|
||||||
|
virtual status_t Undo();
|
||||||
|
virtual status_t Redo();
|
||||||
|
|
||||||
|
virtual void GetName(BString& name);
|
||||||
|
|
||||||
|
// TransformBoxListener interface
|
||||||
|
virtual void PerspectiveBoxDeleted(const PerspectiveBox* box);
|
||||||
|
|
||||||
|
// PerspectiveCommand
|
||||||
|
void SetNewPerspective(
|
||||||
|
BPoint leftTop, BPoint rightTop,
|
||||||
|
BPoint leftBottom, BPoint rightBottom);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PerspectiveBox* fTransformBox;
|
||||||
|
PerspectiveTransformer* fTransformer;
|
||||||
|
|
||||||
|
BPoint fOldLeftTop;
|
||||||
|
BPoint fOldRightTop;
|
||||||
|
BPoint fOldLeftBottom;
|
||||||
|
BPoint fOldRightBottom;
|
||||||
|
|
||||||
|
BPoint fNewLeftTop;
|
||||||
|
BPoint fNewRightTop;
|
||||||
|
BPoint fNewLeftBottom;
|
||||||
|
BPoint fNewRightBottom;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PERSPECTIVE_COMMAND_H
|
||||||
@@ -25,17 +25,7 @@
|
|||||||
#define INSET 8.0
|
#define INSET 8.0
|
||||||
|
|
||||||
|
|
||||||
TransformBoxListener::TransformBoxListener()
|
using namespace TransformBoxStates;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TransformBoxListener::~TransformBoxListener()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
@@ -152,7 +142,6 @@ bool
|
|||||||
TransformBox::MouseDown(BPoint where)
|
TransformBox::MouseDown(BPoint where)
|
||||||
{
|
{
|
||||||
fView->FilterMouse(&where);
|
fView->FilterMouse(&where);
|
||||||
// NOTE: filter mouse here and in MouseMoved only
|
|
||||||
TransformToCanvas(where);
|
TransformToCanvas(where);
|
||||||
|
|
||||||
fDragging = true;
|
fDragging = true;
|
||||||
@@ -172,7 +161,6 @@ void
|
|||||||
TransformBox::MouseMoved(BPoint where)
|
TransformBox::MouseMoved(BPoint where)
|
||||||
{
|
{
|
||||||
fView->FilterMouse(&where);
|
fView->FilterMouse(&where);
|
||||||
// NOTE: filter mouse here and in MouseDown only
|
|
||||||
TransformToCanvas(where);
|
TransformToCanvas(where);
|
||||||
|
|
||||||
if (fMousePos != where) {
|
if (fMousePos != where) {
|
||||||
@@ -236,12 +224,12 @@ TransformBox::Bounds()
|
|||||||
TransformFromCanvas(rb);
|
TransformFromCanvas(rb);
|
||||||
TransformFromCanvas(c);
|
TransformFromCanvas(c);
|
||||||
|
|
||||||
BRect r;
|
BRect bounds;
|
||||||
r.left = min5(lt.x, rt.x, lb.x, rb.x, c.x);
|
bounds.left = min5(lt.x, rt.x, lb.x, rb.x, c.x);
|
||||||
r.top = min5(lt.y, rt.y, lb.y, rb.y, c.y);
|
bounds.top = min5(lt.y, rt.y, lb.y, rb.y, c.y);
|
||||||
r.right = max5(lt.x, rt.x, lb.x, rb.x, c.x);
|
bounds.right = max5(lt.x, rt.x, lb.x, rb.x, c.x);
|
||||||
r.bottom = max5(lt.y, rt.y, lb.y, rb.y, c.y);
|
bounds.bottom = max5(lt.y, rt.y, lb.y, rb.y, c.y);
|
||||||
return r;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
* Authors:
|
* Authors:
|
||||||
* Stephan Aßmus <superstippi@gmx.de>
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TRANSFORM_BOX_H
|
#ifndef TRANSFORM_BOX_H
|
||||||
#define TRANSFORM_BOX_H
|
#define TRANSFORM_BOX_H
|
||||||
|
|
||||||
@@ -14,16 +13,21 @@
|
|||||||
#include "ChannelTransform.h"
|
#include "ChannelTransform.h"
|
||||||
#include "Manipulator.h"
|
#include "Manipulator.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace TransformBoxStates {
|
||||||
|
class DragState;
|
||||||
|
}
|
||||||
|
|
||||||
class Command;
|
class Command;
|
||||||
class StateView;
|
class StateView;
|
||||||
class DragState;
|
|
||||||
class TransformBox;
|
class TransformBox;
|
||||||
class TransformCommand;
|
class TransformCommand;
|
||||||
|
|
||||||
|
|
||||||
class TransformBoxListener {
|
class TransformBoxListener {
|
||||||
public:
|
public:
|
||||||
TransformBoxListener();
|
TransformBoxListener() {}
|
||||||
virtual ~TransformBoxListener();
|
virtual ~TransformBoxListener() {}
|
||||||
|
|
||||||
virtual void TransformBoxDeleted(
|
virtual void TransformBoxDeleted(
|
||||||
const TransformBox* box) = 0;
|
const TransformBox* box) = 0;
|
||||||
@@ -31,9 +35,8 @@ class TransformBoxListener {
|
|||||||
|
|
||||||
class TransformBox : public ChannelTransform,
|
class TransformBox : public ChannelTransform,
|
||||||
public Manipulator {
|
public Manipulator {
|
||||||
public:
|
public:
|
||||||
TransformBox(StateView* view,
|
TransformBox(StateView* view, BRect box);
|
||||||
BRect box);
|
|
||||||
virtual ~TransformBox();
|
virtual ~TransformBox();
|
||||||
|
|
||||||
// Manipulator interface
|
// Manipulator interface
|
||||||
@@ -49,10 +52,10 @@ class TransformBox : public ChannelTransform,
|
|||||||
virtual BRect TrackingBounds(BView* withinView);
|
virtual BRect TrackingBounds(BView* withinView);
|
||||||
|
|
||||||
virtual void ModifiersChanged(uint32 modifiers);
|
virtual void ModifiersChanged(uint32 modifiers);
|
||||||
virtual bool HandleKeyDown(uint32 key, uint32 modifiers,
|
virtual bool HandleKeyDown(uint32 key,
|
||||||
Command** _command);
|
uint32 modifiers, Command** _command);
|
||||||
virtual bool HandleKeyUp(uint32 key, uint32 modifiers,
|
virtual bool HandleKeyUp(uint32 key,
|
||||||
Command** _command);
|
uint32 modifiers, Command** _command);
|
||||||
|
|
||||||
virtual bool UpdateCursor();
|
virtual bool UpdateCursor();
|
||||||
|
|
||||||
@@ -90,15 +93,15 @@ class TransformBox : public ChannelTransform,
|
|||||||
bool AddListener(TransformBoxListener* listener);
|
bool AddListener(TransformBoxListener* listener);
|
||||||
bool RemoveListener(TransformBoxListener* listener);
|
bool RemoveListener(TransformBoxListener* listener);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DragState* _DragStateFor(BPoint canvasWhere,
|
TransformBoxStates::DragState* _DragStateFor(
|
||||||
float canvasZoom);
|
BPoint canvasWhere, float canvasZoom);
|
||||||
void _StrokeBWLine(BView* into,
|
void _StrokeBWLine(BView* into,
|
||||||
BPoint from, BPoint to) const;
|
BPoint from, BPoint to) const;
|
||||||
void _StrokeBWPoint(BView* into,
|
void _StrokeBWPoint(BView* into,
|
||||||
BPoint point,
|
BPoint point, double angle) const;
|
||||||
double angle) const;
|
|
||||||
|
|
||||||
|
private:
|
||||||
BRect fOriginalBox;
|
BRect fOriginalBox;
|
||||||
|
|
||||||
BPoint fLeftTop;
|
BPoint fLeftTop;
|
||||||
@@ -110,7 +113,7 @@ class TransformBox : public ChannelTransform,
|
|||||||
BPoint fPivotOffset;
|
BPoint fPivotOffset;
|
||||||
|
|
||||||
TransformCommand* fCurrentCommand;
|
TransformCommand* fCurrentCommand;
|
||||||
DragState* fCurrentState;
|
TransformBoxStates::DragState* fCurrentState;
|
||||||
|
|
||||||
bool fDragging;
|
bool fDragging;
|
||||||
BPoint fMousePos;
|
BPoint fMousePos;
|
||||||
@@ -120,25 +123,25 @@ class TransformBox : public ChannelTransform,
|
|||||||
|
|
||||||
BList fListeners;
|
BList fListeners;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _NotifyDeleted() const;
|
void _NotifyDeleted() const;
|
||||||
|
|
||||||
// "static" state objects
|
// "static" state objects
|
||||||
StateView* fView;
|
StateView* fView;
|
||||||
|
|
||||||
DragState* fDragLTState;
|
TransformBoxStates::DragState* fDragLTState;
|
||||||
DragState* fDragRTState;
|
TransformBoxStates::DragState* fDragRTState;
|
||||||
DragState* fDragLBState;
|
TransformBoxStates::DragState* fDragLBState;
|
||||||
DragState* fDragRBState;
|
TransformBoxStates::DragState* fDragRBState;
|
||||||
|
|
||||||
DragState* fDragLState;
|
TransformBoxStates::DragState* fDragLState;
|
||||||
DragState* fDragRState;
|
TransformBoxStates::DragState* fDragRState;
|
||||||
DragState* fDragTState;
|
TransformBoxStates::DragState* fDragTState;
|
||||||
DragState* fDragBState;
|
TransformBoxStates::DragState* fDragBState;
|
||||||
|
|
||||||
DragState* fRotateState;
|
TransformBoxStates::DragState* fRotateState;
|
||||||
DragState* fTranslateState;
|
TransformBoxStates::DragState* fTranslateState;
|
||||||
DragState* fOffsetCenterState;
|
TransformBoxStates::DragState* fOffsetCenterState;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRANSFORM_BOX_H
|
#endif // TRANSFORM_BOX_H
|
||||||
|
|||||||
@@ -10,17 +10,14 @@
|
|||||||
#include "TransformBoxStates.h"
|
#include "TransformBoxStates.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
#include <Cursor.h>
|
#include <Cursor.h>
|
||||||
#include <InterfaceDefs.h>
|
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
|
|
||||||
#include "cursors.h"
|
#include "cursors.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
|
|
||||||
#include "TransformBox.h"
|
#include "TransformBox.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +25,9 @@
|
|||||||
#define B_TRANSLATION_CONTEXT "Icon-O-Matic-TransformationBoxStates"
|
#define B_TRANSLATION_CONTEXT "Icon-O-Matic-TransformationBoxStates"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace TransformBoxStates;
|
||||||
|
|
||||||
|
|
||||||
DragState::DragState(TransformBox* parent)
|
DragState::DragState(TransformBox* parent)
|
||||||
:
|
:
|
||||||
fOrigin(0.0, 0.0),
|
fOrigin(0.0, 0.0),
|
||||||
@@ -36,13 +36,6 @@ DragState::DragState(TransformBox* parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
DragState::SetOrigin(BPoint origin)
|
|
||||||
{
|
|
||||||
fOrigin = origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
DragState::ActionName() const
|
DragState::ActionName() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,16 +14,21 @@
|
|||||||
|
|
||||||
#include <agg_trans_affine.h>
|
#include <agg_trans_affine.h>
|
||||||
|
|
||||||
|
|
||||||
class BView;
|
class BView;
|
||||||
class TransformBox;
|
class TransformBox;
|
||||||
|
|
||||||
|
|
||||||
|
namespace TransformBoxStates {
|
||||||
|
|
||||||
// base class
|
// base class
|
||||||
class DragState {
|
class DragState {
|
||||||
public:
|
public:
|
||||||
DragState(TransformBox* parent);
|
DragState(TransformBox* parent);
|
||||||
virtual ~DragState() {}
|
virtual ~DragState() {}
|
||||||
|
|
||||||
virtual void SetOrigin(BPoint origin);
|
virtual void SetOrigin(BPoint origin)
|
||||||
|
{ fOrigin = origin; }
|
||||||
virtual void DragTo(BPoint current, uint32 modifiers) = 0;
|
virtual void DragTo(BPoint current, uint32 modifiers) = 0;
|
||||||
virtual void UpdateViewCursor(BView* view, BPoint current) const = 0;
|
virtual void UpdateViewCursor(BView* view, BPoint current) const = 0;
|
||||||
|
|
||||||
@@ -142,4 +147,6 @@ class OffsetCenterState : public DragState {
|
|||||||
virtual const char* ActionName() const;
|
virtual const char* ActionName() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // TransformBoxStates namespace
|
||||||
|
|
||||||
#endif // TRANSFORM_BOX_STATES_H
|
#endif // TRANSFORM_BOX_STATES_H
|
||||||
|
|||||||
@@ -52,11 +52,12 @@ BuildPlatformMergeObjectPIC <libbe_build>icon_kit.o :
|
|||||||
|
|
||||||
# transformer
|
# transformer
|
||||||
AffineTransformer.cpp
|
AffineTransformer.cpp
|
||||||
|
CompoundStyleTransformer.cpp
|
||||||
ContourTransformer.cpp
|
ContourTransformer.cpp
|
||||||
PathSource.cpp
|
PathSource.cpp
|
||||||
PerspectiveTransformer.cpp
|
PerspectiveTransformer.cpp
|
||||||
StrokeTransformer.cpp
|
StrokeTransformer.cpp
|
||||||
Transformer.cpp
|
StyleTransformer.cpp
|
||||||
TransformerFactory.cpp
|
TransformerFactory.cpp
|
||||||
|
|
||||||
Icon.cpp
|
Icon.cpp
|
||||||
|
|||||||
@@ -50,11 +50,12 @@ BuildPlatformStaticLibrary libicon_build.a :
|
|||||||
|
|
||||||
# transformer
|
# transformer
|
||||||
AffineTransformer.cpp
|
AffineTransformer.cpp
|
||||||
|
CompoundStyleTransformer.cpp
|
||||||
ContourTransformer.cpp
|
ContourTransformer.cpp
|
||||||
PathSource.cpp
|
PathSource.cpp
|
||||||
PerspectiveTransformer.cpp
|
PerspectiveTransformer.cpp
|
||||||
StrokeTransformer.cpp
|
StrokeTransformer.cpp
|
||||||
Transformer.cpp
|
StyleTransformer.cpp
|
||||||
TransformerFactory.cpp
|
TransformerFactory.cpp
|
||||||
|
|
||||||
Icon.cpp
|
Icon.cpp
|
||||||
|
|||||||
+210
-112
@@ -20,108 +20,142 @@
|
|||||||
#include <agg_span_image_filter_rgba.h>
|
#include <agg_span_image_filter_rgba.h>
|
||||||
#include <agg_span_gradient.h>
|
#include <agg_span_gradient.h>
|
||||||
#include <agg_span_interpolator_linear.h>
|
#include <agg_span_interpolator_linear.h>
|
||||||
|
#include <agg_span_interpolator_trans.h>
|
||||||
|
|
||||||
|
#include "CompoundStyleTransformer.h"
|
||||||
#include "GradientTransformable.h"
|
#include "GradientTransformable.h"
|
||||||
#include "Icon.h"
|
#include "Icon.h"
|
||||||
#include "Shape.h"
|
#include "Shape.h"
|
||||||
#include "Style.h"
|
#include "Style.h"
|
||||||
|
#include "StyleTransformer.h"
|
||||||
#include "VectorPath.h"
|
#include "VectorPath.h"
|
||||||
|
|
||||||
using std::nothrow;
|
using std::nothrow;
|
||||||
|
|
||||||
class IconRenderer::StyleHandler {
|
class IconRenderer::StyleHandler {
|
||||||
struct StyleItem {
|
struct StyleItem {
|
||||||
Style* style;
|
const Style* style;
|
||||||
Transformation transformation;
|
StyleTransformer* transformer;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifdef ICON_O_MATIC
|
#ifdef ICON_O_MATIC
|
||||||
StyleHandler(::GammaTable& gammaTable, bool showReferences)
|
StyleHandler(::GammaTable& gammaTable,
|
||||||
: fStyles(20),
|
bool showReferences);
|
||||||
fGammaTable(gammaTable),
|
|
||||||
fShowReferences(showReferences),
|
|
||||||
fTransparent(0, 0, 0, 0),
|
|
||||||
fColor(0, 0, 0, 0)
|
|
||||||
{}
|
|
||||||
#else
|
#else
|
||||||
StyleHandler(::GammaTable& gammaTable)
|
StyleHandler(::GammaTable& gammaTable);
|
||||||
: fStyles(20),
|
|
||||||
fGammaTable(gammaTable),
|
|
||||||
fTransparent(0, 0, 0, 0),
|
|
||||||
fColor(0, 0, 0, 0)
|
|
||||||
{}
|
|
||||||
#endif // ICON_O_MATIC
|
|
||||||
|
|
||||||
~StyleHandler()
|
|
||||||
{
|
|
||||||
int32 count = fStyles.CountItems();
|
|
||||||
for (int32 i = 0; i < count; i++)
|
|
||||||
delete (StyleItem*)fStyles.ItemAtFast(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_solid(unsigned styleIndex) const
|
|
||||||
{
|
|
||||||
StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(styleIndex);
|
|
||||||
if (!styleItem)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (styleItem->style->Gradient())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef ICON_O_MATIC
|
|
||||||
if (styleItem->style->Bitmap() && fShowReferences)
|
|
||||||
return false;
|
|
||||||
#endif // ICON_O_MATIC
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const agg::rgba8& color(unsigned styleIndex);
|
|
||||||
|
|
||||||
void generate_span(agg::rgba8* span, int x, int y,
|
|
||||||
unsigned len, unsigned styleIndex);
|
|
||||||
|
|
||||||
bool AddStyle(Style* style, const Transformation& transformation)
|
|
||||||
{
|
|
||||||
if (!style)
|
|
||||||
return false;
|
|
||||||
StyleItem* item = new (nothrow) StyleItem;
|
|
||||||
if (!item)
|
|
||||||
return false;
|
|
||||||
item->style = style;
|
|
||||||
// if the style uses a gradient, the transformation
|
|
||||||
// is based on the gradient transformation
|
|
||||||
if (Gradient* gradient = style->Gradient()) {
|
|
||||||
item->transformation = *gradient;
|
|
||||||
item->transformation.multiply(transformation);
|
|
||||||
} else {
|
|
||||||
item->transformation = transformation;
|
|
||||||
}
|
|
||||||
item->transformation.invert();
|
|
||||||
return fStyles.AddItem((void*)item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<class GradientFunction>
|
|
||||||
void _GenerateGradient(agg::rgba8* span, int x, int y, unsigned len,
|
|
||||||
GradientFunction function, int32 start, int32 end,
|
|
||||||
const agg::rgba8* gradientColors, Transformation& gradientTransform);
|
|
||||||
#ifdef ICON_O_MATIC
|
|
||||||
void _GenerateImage(agg::rgba8* span, int x, int y,
|
|
||||||
unsigned len, Style* style, Transformation& transform);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BList fStyles;
|
~StyleHandler();
|
||||||
::GammaTable& fGammaTable;
|
|
||||||
|
bool AddStyle(const Style* style,
|
||||||
|
const Transformable& transformation,
|
||||||
|
const Container<Transformer>* transformers);
|
||||||
|
|
||||||
|
bool is_solid(unsigned styleIndex) const;
|
||||||
|
const agg::rgba8& color(unsigned styleIndex);
|
||||||
|
void generate_span(agg::rgba8* span, int x, int y,
|
||||||
|
unsigned len, unsigned styleIndex);
|
||||||
|
private:
|
||||||
|
StyleTransformer* _MergeTransformers(
|
||||||
|
const Transformable* styleTransformation,
|
||||||
|
const Container<Transformer>* transformers,
|
||||||
|
const Transformable* shapeTransformation);
|
||||||
|
|
||||||
|
template<class GradientFunction>
|
||||||
|
void _GenerateGradient(agg::rgba8* span,
|
||||||
|
int x, int y, unsigned len,
|
||||||
|
GradientFunction function,
|
||||||
|
int32 start, int32 end,
|
||||||
|
const agg::rgba8* gradientColors,
|
||||||
|
StyleTransformer* transformer);
|
||||||
#ifdef ICON_O_MATIC
|
#ifdef ICON_O_MATIC
|
||||||
bool fShowReferences;
|
void _GenerateImage(agg::rgba8* span,
|
||||||
|
int x, int y, unsigned len,
|
||||||
|
const Style* style,
|
||||||
|
StyleTransformer* transformer);
|
||||||
#endif
|
#endif
|
||||||
agg::rgba8 fTransparent;
|
|
||||||
agg::rgba8 fColor;
|
private:
|
||||||
|
BList fStyles;
|
||||||
|
::GammaTable& fGammaTable;
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
bool fShowReferences;
|
||||||
|
#endif
|
||||||
|
agg::rgba8 fTransparent;
|
||||||
|
agg::rgba8 fColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
IconRenderer::StyleHandler::StyleHandler(::GammaTable& gammaTable, bool showReferences)
|
||||||
|
: fStyles(20),
|
||||||
|
fGammaTable(gammaTable),
|
||||||
|
fShowReferences(showReferences),
|
||||||
|
fTransparent(0, 0, 0, 0),
|
||||||
|
fColor(0, 0, 0, 0)
|
||||||
|
{}
|
||||||
|
#else
|
||||||
|
IconRenderer::StyleHandler::StyleHandler(::GammaTable& gammaTable)
|
||||||
|
: fStyles(20),
|
||||||
|
fGammaTable(gammaTable),
|
||||||
|
fTransparent(0, 0, 0, 0),
|
||||||
|
fColor(0, 0, 0, 0)
|
||||||
|
{}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
IconRenderer::StyleHandler::~StyleHandler()
|
||||||
|
{
|
||||||
|
int32 count = fStyles.CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
StyleItem* item = (StyleItem*)fStyles.ItemAtFast(i);
|
||||||
|
delete item->transformer;
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
IconRenderer::StyleHandler::AddStyle(const Style* style,
|
||||||
|
const Transformable& transformation, const Container<Transformer>* transformers)
|
||||||
|
{
|
||||||
|
if (!style)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
StyleItem* item = new (nothrow) StyleItem;
|
||||||
|
if (!item)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
item->style = style;
|
||||||
|
|
||||||
|
item->transformer = _MergeTransformers(style->Gradient(), transformers, &transformation);
|
||||||
|
item->transformer->Invert();
|
||||||
|
|
||||||
|
return fStyles.AddItem((void*)item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
IconRenderer::StyleHandler::is_solid(unsigned styleIndex) const
|
||||||
|
{
|
||||||
|
StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(styleIndex);
|
||||||
|
if (!styleItem)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (styleItem->style->Gradient())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
if (styleItem->style->Bitmap() && fShowReferences)
|
||||||
|
return false;
|
||||||
|
#endif // ICON_O_MATIC
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const agg::rgba8&
|
const agg::rgba8&
|
||||||
IconRenderer::StyleHandler::color(unsigned styleIndex)
|
IconRenderer::StyleHandler::color(unsigned styleIndex)
|
||||||
{
|
{
|
||||||
@@ -164,12 +198,12 @@ IconRenderer::StyleHandler::generate_span(agg::rgba8* span, int x, int y,
|
|||||||
|
|
||||||
#ifdef ICON_O_MATIC
|
#ifdef ICON_O_MATIC
|
||||||
if (styleItem->style->Bitmap()) {
|
if (styleItem->style->Bitmap()) {
|
||||||
_GenerateImage(span, x, y, len, styleItem->style, styleItem->transformation);
|
_GenerateImage(span, x, y, len, styleItem->style, styleItem->transformer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif // ICON_O_MATIC
|
#endif // ICON_O_MATIC
|
||||||
|
|
||||||
Style* style = styleItem->style;
|
const Style* style = styleItem->style;
|
||||||
Gradient* gradient = style->Gradient();
|
Gradient* gradient = style->Gradient();
|
||||||
const agg::rgba8* colors = style->GammaCorrectedColors(fGammaTable);
|
const agg::rgba8* colors = style->GammaCorrectedColors(fGammaTable);
|
||||||
|
|
||||||
@@ -177,70 +211,132 @@ IconRenderer::StyleHandler::generate_span(agg::rgba8* span, int x, int y,
|
|||||||
case GRADIENT_LINEAR: {
|
case GRADIENT_LINEAR: {
|
||||||
agg::gradient_x function;
|
agg::gradient_x function;
|
||||||
_GenerateGradient(span, x, y, len, function, -64, 64, colors,
|
_GenerateGradient(span, x, y, len, function, -64, 64, colors,
|
||||||
styleItem->transformation);
|
styleItem->transformer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GRADIENT_CIRCULAR: {
|
case GRADIENT_CIRCULAR: {
|
||||||
agg::gradient_radial function;
|
agg::gradient_radial function;
|
||||||
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
||||||
styleItem->transformation);
|
styleItem->transformer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GRADIENT_DIAMOND: {
|
case GRADIENT_DIAMOND: {
|
||||||
agg::gradient_diamond function;
|
agg::gradient_diamond function;
|
||||||
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
||||||
styleItem->transformation);
|
styleItem->transformer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GRADIENT_CONIC: {
|
case GRADIENT_CONIC: {
|
||||||
agg::gradient_conic function;
|
agg::gradient_conic function;
|
||||||
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
||||||
styleItem->transformation);
|
styleItem->transformer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GRADIENT_XY: {
|
case GRADIENT_XY: {
|
||||||
agg::gradient_xy function;
|
agg::gradient_xy function;
|
||||||
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
||||||
styleItem->transformation);
|
styleItem->transformer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GRADIENT_SQRT_XY: {
|
case GRADIENT_SQRT_XY: {
|
||||||
agg::gradient_sqrt_xy function;
|
agg::gradient_sqrt_xy function;
|
||||||
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
_GenerateGradient(span, x, y, len, function, 0, 64, colors,
|
||||||
styleItem->transformation);
|
styleItem->transformer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StyleTransformer*
|
||||||
|
IconRenderer::StyleHandler::_MergeTransformers(const Transformable* styleTransformation,
|
||||||
|
const Container<Transformer>* transformers, const Transformable* shapeTransformation)
|
||||||
|
{
|
||||||
|
// Figure out how large to make the array
|
||||||
|
int32 count = 0;
|
||||||
|
if (styleTransformation != NULL)
|
||||||
|
count++;
|
||||||
|
for (int i = 0; i < transformers->CountItems(); i++) {
|
||||||
|
if (dynamic_cast<StyleTransformer*>(transformers->ItemAtFast(i)))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
|
||||||
|
// Populate the array
|
||||||
|
StyleTransformer** styleTransformers = new (nothrow) StyleTransformer*[count];
|
||||||
|
if (styleTransformers == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
if (styleTransformation != NULL)
|
||||||
|
styleTransformers[i++] = new (nothrow) Transformable(*styleTransformation);
|
||||||
|
for (int j = 0; j < transformers->CountItems(); j++) {
|
||||||
|
Transformer* transformer = transformers->ItemAtFast(j);
|
||||||
|
if (dynamic_cast<StyleTransformer*>(transformer) != NULL) {
|
||||||
|
styleTransformers[i++]
|
||||||
|
= dynamic_cast<StyleTransformer*>(transformer->Clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
styleTransformers[i++] = new (nothrow) Transformable(*shapeTransformation);
|
||||||
|
|
||||||
|
CompoundStyleTransformer* styleTransformer
|
||||||
|
= new (nothrow) CompoundStyleTransformer(styleTransformers, count);
|
||||||
|
if (styleTransformer == NULL) {
|
||||||
|
delete[] styleTransformers;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return styleTransformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class GradientFunction>
|
template<class GradientFunction>
|
||||||
void
|
void
|
||||||
IconRenderer::StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y,
|
IconRenderer::StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y,
|
||||||
unsigned len, GradientFunction function, int32 start, int32 end,
|
unsigned len, GradientFunction function, int32 start, int32 end,
|
||||||
const agg::rgba8* gradientColors, Transformation& gradientTransform)
|
const agg::rgba8* gradientColors, StyleTransformer* transformer)
|
||||||
{
|
{
|
||||||
|
// TODO: performance could potentially be improved by avoiding recreating
|
||||||
|
// these objects on every span
|
||||||
typedef agg::pod_auto_array<agg::rgba8, 256> ColorArray;
|
typedef agg::pod_auto_array<agg::rgba8, 256> ColorArray;
|
||||||
typedef agg::span_interpolator_linear<> Interpolator;
|
|
||||||
typedef agg::span_gradient<agg::rgba8,
|
|
||||||
Interpolator,
|
|
||||||
GradientFunction,
|
|
||||||
ColorArray> GradientGenerator;
|
|
||||||
|
|
||||||
Interpolator interpolator(gradientTransform);
|
|
||||||
|
|
||||||
ColorArray array(gradientColors);
|
ColorArray array(gradientColors);
|
||||||
GradientGenerator gradientGenerator(interpolator, function, array,
|
|
||||||
start, end);
|
|
||||||
|
|
||||||
gradientGenerator.generate(span, x, y, len);
|
if (transformer->IsLinear()) {
|
||||||
|
typedef agg::span_interpolator_linear
|
||||||
|
<StyleTransformer> Interpolator;
|
||||||
|
typedef agg::span_gradient<agg::rgba8,
|
||||||
|
Interpolator,
|
||||||
|
GradientFunction,
|
||||||
|
ColorArray> GradientGenerator;
|
||||||
|
|
||||||
|
Interpolator interpolator(*transformer);
|
||||||
|
|
||||||
|
GradientGenerator gradientGenerator(interpolator, function, array,
|
||||||
|
start, end);
|
||||||
|
|
||||||
|
gradientGenerator.generate(span, x, y, len);
|
||||||
|
} else {
|
||||||
|
typedef agg::span_interpolator_trans
|
||||||
|
<StyleTransformer> Interpolator;
|
||||||
|
typedef agg::span_gradient<agg::rgba8,
|
||||||
|
Interpolator,
|
||||||
|
GradientFunction,
|
||||||
|
ColorArray> GradientGenerator;
|
||||||
|
|
||||||
|
Interpolator interpolator(*transformer);
|
||||||
|
|
||||||
|
GradientGenerator gradientGenerator(interpolator, function, array,
|
||||||
|
start, end);
|
||||||
|
|
||||||
|
gradientGenerator.generate(span, x, y, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef ICON_O_MATIC
|
#ifdef ICON_O_MATIC
|
||||||
void
|
void
|
||||||
IconRenderer::StyleHandler::_GenerateImage(agg::rgba8* span, int x, int y,
|
IconRenderer::StyleHandler::_GenerateImage(agg::rgba8* span, int x, int y,
|
||||||
unsigned len, Style* style, Transformation& transform)
|
unsigned len, const Style* style, StyleTransformer* transformer)
|
||||||
{
|
{
|
||||||
// bitmap
|
// bitmap
|
||||||
BBitmap* bbitmap = style->Bitmap();
|
BBitmap* bbitmap = style->Bitmap();
|
||||||
@@ -252,13 +348,16 @@ IconRenderer::StyleHandler::_GenerateImage(agg::rgba8* span, int x, int y,
|
|||||||
PixelFormat pixf_img(bitmap);
|
PixelFormat pixf_img(bitmap);
|
||||||
|
|
||||||
// image interpolator
|
// image interpolator
|
||||||
typedef agg::span_interpolator_linear<> interpolator_type;
|
// TODO: performance could be improved by using agg_interpolator_linear
|
||||||
interpolator_type interpolator(transform);
|
// where possible, similar to what _GenerateGradient does.
|
||||||
|
typedef agg::span_interpolator_trans<StyleTransformer>
|
||||||
|
interpolator_type;
|
||||||
|
interpolator_type interpolator(*transformer);
|
||||||
|
|
||||||
// image accessor attached to pixel format of bitmap
|
// image accessor attached to pixel format of bitmap
|
||||||
typedef agg::image_accessor_wrap<PixelFormat,
|
typedef agg::image_accessor_clip<PixelFormat> source_type;
|
||||||
agg::wrap_mode_repeat, agg::wrap_mode_repeat> source_type;
|
agg::rgba8 background(0, 0, 0, 0);
|
||||||
source_type source(pixf_img);
|
source_type source(pixf_img, background);
|
||||||
|
|
||||||
// image filter (nearest neighbor)
|
// image filter (nearest neighbor)
|
||||||
typedef agg::span_image_filter_rgba_nn<
|
typedef agg::span_image_filter_rgba_nn<
|
||||||
@@ -424,7 +523,7 @@ IconRenderer::Demultiply()
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
typedef agg::conv_transform<VertexSource, Transformation> ScaledPath;
|
typedef agg::conv_transform<VertexSource, Transformable> ScaledPath;
|
||||||
typedef agg::conv_transform<ScaledPath, HintingTransformer> HintedPath;
|
typedef agg::conv_transform<ScaledPath, HintingTransformer> HintedPath;
|
||||||
|
|
||||||
|
|
||||||
@@ -467,11 +566,8 @@ IconRenderer::_Render(const BRect& r)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transformation transform(*shape);
|
Transformable transform(*shape);
|
||||||
transform.multiply(fGlobalTransform);
|
transform.multiply(fGlobalTransform);
|
||||||
// NOTE: this works only because "agg::trans_affine",
|
|
||||||
// "Transformable" and "Transformation" are all the
|
|
||||||
// same thing
|
|
||||||
|
|
||||||
Style* style = shape->Style();
|
Style* style = shape->Style();
|
||||||
if (!style)
|
if (!style)
|
||||||
@@ -483,9 +579,11 @@ IconRenderer::_Render(const BRect& r)
|
|||||||
Gradient* gradient = style->Gradient();
|
Gradient* gradient = style->Gradient();
|
||||||
bool styleAdded = false;
|
bool styleAdded = false;
|
||||||
if (gradient && !gradient->InheritTransformation()) {
|
if (gradient && !gradient->InheritTransformation()) {
|
||||||
styleAdded = styleHandler.AddStyle(style, fGlobalTransform);
|
styleAdded = styleHandler.AddStyle(
|
||||||
|
style, fGlobalTransform, NULL);
|
||||||
} else {
|
} else {
|
||||||
styleAdded = styleHandler.AddStyle(style, transform);
|
styleAdded = styleHandler.AddStyle(
|
||||||
|
style, transform, shape->Transformers());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!styleAdded) {
|
if (!styleAdded) {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <agg_trans_affine.h>
|
#include <agg_trans_affine.h>
|
||||||
|
|
||||||
#include "IconBuild.h"
|
#include "IconBuild.h"
|
||||||
|
#include "Transformable.h"
|
||||||
|
|
||||||
|
|
||||||
class BBitmap;
|
class BBitmap;
|
||||||
@@ -47,8 +48,6 @@ typedef agg::span_allocator<agg::rgba8> SpanAllocator;
|
|||||||
typedef agg::rasterizer_compound_aa
|
typedef agg::rasterizer_compound_aa
|
||||||
<agg::rasterizer_sl_clip_dbl> CompoundRasterizer;
|
<agg::rasterizer_sl_clip_dbl> CompoundRasterizer;
|
||||||
|
|
||||||
typedef agg::trans_affine Transformation;
|
|
||||||
|
|
||||||
class IconRenderer {
|
class IconRenderer {
|
||||||
public:
|
public:
|
||||||
IconRenderer(BBitmap* bitmap);
|
IconRenderer(BBitmap* bitmap);
|
||||||
@@ -110,7 +109,7 @@ class IconRenderer {
|
|||||||
|
|
||||||
CompoundRasterizer fRasterizer;
|
CompoundRasterizer fRasterizer;
|
||||||
|
|
||||||
Transformation fGlobalTransform;
|
Transformable fGlobalTransform;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,11 +59,12 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
|
|
||||||
# transformer
|
# transformer
|
||||||
AffineTransformer.cpp
|
AffineTransformer.cpp
|
||||||
|
CompoundStyleTransformer.cpp
|
||||||
ContourTransformer.cpp
|
ContourTransformer.cpp
|
||||||
PathSource.cpp
|
PathSource.cpp
|
||||||
PerspectiveTransformer.cpp
|
PerspectiveTransformer.cpp
|
||||||
StrokeTransformer.cpp
|
StrokeTransformer.cpp
|
||||||
Transformer.cpp
|
StyleTransformer.cpp
|
||||||
TransformerFactory.cpp
|
TransformerFactory.cpp
|
||||||
|
|
||||||
Icon.cpp
|
Icon.cpp
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006, Haiku. All rights reserved.
|
* Copyright 2006, 2023, Haiku. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Stephan Aßmus <superstippi@gmx.de>
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FlatIconImporter.h"
|
#include "FlatIconImporter.h"
|
||||||
@@ -435,7 +436,7 @@ FlatIconImporter::_ParsePaths(LittleEndianBuffer& buffer,
|
|||||||
|
|
||||||
// _ReadTransformer
|
// _ReadTransformer
|
||||||
static Transformer*
|
static Transformer*
|
||||||
_ReadTransformer(LittleEndianBuffer& buffer, VertexSource& source)
|
_ReadTransformer(LittleEndianBuffer& buffer, VertexSource& source, Shape* shape)
|
||||||
{
|
{
|
||||||
uint8 transformerType;
|
uint8 transformerType;
|
||||||
if (!buffer.Read(transformerType))
|
if (!buffer.Read(transformerType))
|
||||||
@@ -479,9 +480,19 @@ _ReadTransformer(LittleEndianBuffer& buffer, VertexSource& source)
|
|||||||
}
|
}
|
||||||
case TRANSFORMER_TYPE_PERSPECTIVE: {
|
case TRANSFORMER_TYPE_PERSPECTIVE: {
|
||||||
PerspectiveTransformer* perspective
|
PerspectiveTransformer* perspective
|
||||||
= new (nothrow) PerspectiveTransformer(source);
|
= new (nothrow) PerspectiveTransformer(source, shape);
|
||||||
// TODO: upgrade AGG to be able to support storage of
|
if (!perspective)
|
||||||
// trans_perspective
|
return NULL;
|
||||||
|
double matrix[9];
|
||||||
|
for (int32 i = 0; i < 9; i++) {
|
||||||
|
float value;
|
||||||
|
if (!read_float_24(buffer, value)) {
|
||||||
|
delete perspective;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
matrix[i] = value;
|
||||||
|
}
|
||||||
|
perspective->load_from(matrix);
|
||||||
return perspective;
|
return perspective;
|
||||||
}
|
}
|
||||||
case TRANSFORMER_TYPE_STROKE: {
|
case TRANSFORMER_TYPE_STROKE: {
|
||||||
@@ -601,7 +612,7 @@ FlatIconImporter::_ReadPathSourceShape(LittleEndianBuffer& buffer,
|
|||||||
return NULL;
|
return NULL;
|
||||||
for (uint32 i = 0; i < transformerCount; i++) {
|
for (uint32 i = 0; i < transformerCount; i++) {
|
||||||
Transformer* transformer
|
Transformer* transformer
|
||||||
= _ReadTransformer(buffer, shape->VertexSource());
|
= _ReadTransformer(buffer, shape->VertexSource(), shape);
|
||||||
if (transformer && !shape->Transformers()->AddItem(transformer)) {
|
if (transformer && !shape->Transformers()->AddItem(transformer)) {
|
||||||
delete transformer;
|
delete transformer;
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -651,7 +662,3 @@ FlatIconImporter::_ParseShapes(LittleEndianBuffer& buffer,
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2007, 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
#ifndef VERTEX_SOURCE_H
|
||||||
|
#define VERTEX_SOURCE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "IconBuild.h"
|
||||||
|
|
||||||
|
|
||||||
|
_BEGIN_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
class VertexSource {
|
||||||
|
public:
|
||||||
|
VertexSource() {}
|
||||||
|
virtual ~VertexSource() {}
|
||||||
|
|
||||||
|
virtual void rewind(unsigned path_id) = 0;
|
||||||
|
virtual unsigned vertex(double* x, double* y) = 0;
|
||||||
|
|
||||||
|
/*! Determines whether open paths should be closed or left open. */
|
||||||
|
virtual bool WantsOpenPaths() const = 0;
|
||||||
|
virtual double ApproximationScale() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
_END_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VERTEX_SOURCE_H
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
# include "PropertyObject.h"
|
# include "PropertyObject.h"
|
||||||
#endif // ICON_O_MATIC
|
#endif // ICON_O_MATIC
|
||||||
#include "Container.h"
|
#include "Container.h"
|
||||||
|
#include "PathTransformer.h"
|
||||||
#include "Style.h"
|
#include "Style.h"
|
||||||
#include "TransformerFactory.h"
|
#include "TransformerFactory.h"
|
||||||
#include "VectorPath.h"
|
#include "VectorPath.h"
|
||||||
@@ -130,7 +131,7 @@ Shape::Shape(const Shape& other)
|
|||||||
int32 count = other.Transformers()->CountItems();
|
int32 count = other.Transformers()->CountItems();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
Transformer* original = other.Transformers()->ItemAtFast(i);
|
Transformer* original = other.Transformers()->ItemAtFast(i);
|
||||||
Transformer* cloned = original->Clone(fPathSource);
|
Transformer* cloned = original->Clone();
|
||||||
if (!fTransformers.AddItem(cloned)) {
|
if (!fTransformers.AddItem(cloned)) {
|
||||||
delete cloned;
|
delete cloned;
|
||||||
break;
|
break;
|
||||||
@@ -181,7 +182,7 @@ Shape::Unarchive(BMessage* archive)
|
|||||||
i++) {
|
i++) {
|
||||||
Transformer* transformer
|
Transformer* transformer
|
||||||
= TransformerFactory::TransformerFor(
|
= TransformerFactory::TransformerFor(
|
||||||
&transformerArchive, VertexSource());
|
&transformerArchive, VertexSource(), this);
|
||||||
if (!transformer || !fTransformers.AddItem(transformer)) {
|
if (!transformer || !fTransformers.AddItem(transformer)) {
|
||||||
delete transformer;
|
delete transformer;
|
||||||
}
|
}
|
||||||
@@ -452,9 +453,11 @@ Shape::VertexSource()
|
|||||||
|
|
||||||
int32 count = fTransformers.CountItems();
|
int32 count = fTransformers.CountItems();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
Transformer* t = (Transformer*)fTransformers.ItemAtFast(i);
|
PathTransformer* t = dynamic_cast<PathTransformer*>(fTransformers.ItemAtFast(i));
|
||||||
t->SetSource(*source);
|
if (t != NULL) {
|
||||||
source = t;
|
t->SetSource(*source);
|
||||||
|
source = t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fNeedsUpdate) {
|
if (fNeedsUpdate) {
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class Style {
|
|||||||
// alpha only applies to bitmaps
|
// alpha only applies to bitmaps
|
||||||
void SetAlpha(uint8 alpha)
|
void SetAlpha(uint8 alpha)
|
||||||
{ fAlpha = alpha; Notify(); }
|
{ fAlpha = alpha; Notify(); }
|
||||||
uint8 Alpha()
|
uint8 Alpha() const
|
||||||
{ return fAlpha; }
|
{ return fAlpha; }
|
||||||
#endif // ICON_O_MATIC
|
#endif // ICON_O_MATIC
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009, Haiku.
|
* Copyright 2006-2009, 2023, Haiku.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Stephan Aßmus <superstippi@gmx.de>
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Transformable.h"
|
#include "Transformable.h"
|
||||||
@@ -11,31 +12,78 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// constructor
|
|
||||||
Transformable::Transformable()
|
Transformable::Transformable()
|
||||||
: agg::trans_affine()
|
: agg::trans_affine()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy constructor
|
|
||||||
Transformable::Transformable(const Transformable& other)
|
Transformable::Transformable(const Transformable& other)
|
||||||
: agg::trans_affine(other)
|
: agg::trans_affine(other)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
|
||||||
Transformable::~Transformable()
|
Transformable::~Transformable()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreTo
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Transformable::Invert()
|
||||||
|
{
|
||||||
|
if (!IsIdentity()) {
|
||||||
|
invert();
|
||||||
|
TransformationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Transformable::InverseTransform(double* x, double* y) const
|
||||||
|
{
|
||||||
|
inverse_transform(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Transformable::InverseTransform(BPoint* point) const
|
||||||
|
{
|
||||||
|
if (point) {
|
||||||
|
double x = point->x;
|
||||||
|
double y = point->y;
|
||||||
|
|
||||||
|
inverse_transform(&x, &y);
|
||||||
|
|
||||||
|
point->x = x;
|
||||||
|
point->y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BPoint
|
||||||
|
Transformable::InverseTransform(const BPoint& point) const
|
||||||
|
{
|
||||||
|
BPoint p(point);
|
||||||
|
InverseTransform(&p);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Transformable::StoreTo(double matrix[matrix_size]) const
|
Transformable::StoreTo(double matrix[matrix_size]) const
|
||||||
{
|
{
|
||||||
store_to(matrix);
|
store_to(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadFrom
|
|
||||||
void
|
void
|
||||||
Transformable::LoadFrom(const double matrix[matrix_size])
|
Transformable::LoadFrom(const double matrix[matrix_size])
|
||||||
{
|
{
|
||||||
@@ -50,7 +98,7 @@ Transformable::LoadFrom(const double matrix[matrix_size])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTransform
|
|
||||||
void
|
void
|
||||||
Transformable::SetTransform(const Transformable& other)
|
Transformable::SetTransform(const Transformable& other)
|
||||||
{
|
{
|
||||||
@@ -60,7 +108,7 @@ Transformable::SetTransform(const Transformable& other)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator=
|
|
||||||
Transformable&
|
Transformable&
|
||||||
Transformable::operator=(const Transformable& other)
|
Transformable::operator=(const Transformable& other)
|
||||||
{
|
{
|
||||||
@@ -72,7 +120,7 @@ Transformable::operator=(const Transformable& other)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply
|
|
||||||
Transformable&
|
Transformable&
|
||||||
Transformable::Multiply(const Transformable& other)
|
Transformable::Multiply(const Transformable& other)
|
||||||
{
|
{
|
||||||
@@ -83,7 +131,7 @@ Transformable::Multiply(const Transformable& other)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset
|
|
||||||
void
|
void
|
||||||
Transformable::Reset()
|
Transformable::Reset()
|
||||||
{
|
{
|
||||||
@@ -93,17 +141,7 @@ Transformable::Reset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invert
|
|
||||||
void
|
|
||||||
Transformable::Invert()
|
|
||||||
{
|
|
||||||
if (!IsIdentity()) {
|
|
||||||
invert();
|
|
||||||
TransformationChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsIdentity
|
|
||||||
bool
|
bool
|
||||||
Transformable::IsIdentity() const
|
Transformable::IsIdentity() const
|
||||||
{
|
{
|
||||||
@@ -119,7 +157,7 @@ Transformable::IsIdentity() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTranslationOnly
|
|
||||||
bool
|
bool
|
||||||
Transformable::IsTranslationOnly() const
|
Transformable::IsTranslationOnly() const
|
||||||
{
|
{
|
||||||
@@ -133,7 +171,7 @@ Transformable::IsTranslationOnly() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsNotDistorted
|
|
||||||
bool
|
bool
|
||||||
Transformable::IsNotDistorted() const
|
Transformable::IsNotDistorted() const
|
||||||
{
|
{
|
||||||
@@ -142,7 +180,7 @@ Transformable::IsNotDistorted() const
|
|||||||
return (m[0] == m[3]);
|
return (m[0] == m[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValid
|
|
||||||
bool
|
bool
|
||||||
Transformable::IsValid() const
|
Transformable::IsValid() const
|
||||||
{
|
{
|
||||||
@@ -151,7 +189,7 @@ Transformable::IsValid() const
|
|||||||
return ((m[0] * m[3] - m[1] * m[2]) != 0.0);
|
return ((m[0] * m[3] - m[1] * m[2]) != 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator==
|
|
||||||
bool
|
bool
|
||||||
Transformable::operator==(const Transformable& other) const
|
Transformable::operator==(const Transformable& other) const
|
||||||
{
|
{
|
||||||
@@ -162,74 +200,13 @@ Transformable::operator==(const Transformable& other) const
|
|||||||
return memcmp(m1, m2, sizeof(m1)) == 0;
|
return memcmp(m1, m2, sizeof(m1)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator!=
|
|
||||||
bool
|
bool
|
||||||
Transformable::operator!=(const Transformable& other) const
|
Transformable::operator!=(const Transformable& other) const
|
||||||
{
|
{
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform
|
|
||||||
void
|
|
||||||
Transformable::Transform(double* x, double* y) const
|
|
||||||
{
|
|
||||||
transform(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform
|
|
||||||
void
|
|
||||||
Transformable::Transform(BPoint* point) const
|
|
||||||
{
|
|
||||||
if (point) {
|
|
||||||
double x = point->x;
|
|
||||||
double y = point->y;
|
|
||||||
|
|
||||||
transform(&x, &y);
|
|
||||||
|
|
||||||
point->x = x;
|
|
||||||
point->y = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform
|
|
||||||
BPoint
|
|
||||||
Transformable::Transform(const BPoint& point) const
|
|
||||||
{
|
|
||||||
BPoint p(point);
|
|
||||||
Transform(&p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
// InverseTransform
|
|
||||||
void
|
|
||||||
Transformable::InverseTransform(double* x, double* y) const
|
|
||||||
{
|
|
||||||
inverse_transform(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// InverseTransform
|
|
||||||
void
|
|
||||||
Transformable::InverseTransform(BPoint* point) const
|
|
||||||
{
|
|
||||||
if (point) {
|
|
||||||
double x = point->x;
|
|
||||||
double y = point->y;
|
|
||||||
|
|
||||||
inverse_transform(&x, &y);
|
|
||||||
|
|
||||||
point->x = x;
|
|
||||||
point->y = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// InverseTransform
|
|
||||||
BPoint
|
|
||||||
Transformable::InverseTransform(const BPoint& point) const
|
|
||||||
{
|
|
||||||
BPoint p(point);
|
|
||||||
InverseTransform(&p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float
|
inline float
|
||||||
min4(float a, float b, float c, float d)
|
min4(float a, float b, float c, float d)
|
||||||
@@ -237,13 +214,14 @@ min4(float a, float b, float c, float d)
|
|||||||
return min_c(a, min_c(b, min_c(c, d)));
|
return min_c(a, min_c(b, min_c(c, d)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline float
|
inline float
|
||||||
max4(float a, float b, float c, float d)
|
max4(float a, float b, float c, float d)
|
||||||
{
|
{
|
||||||
return max_c(a, max_c(b, max_c(c, d)));
|
return max_c(a, max_c(b, max_c(c, d)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransformBounds
|
|
||||||
BRect
|
BRect
|
||||||
Transformable::TransformBounds(BRect bounds) const
|
Transformable::TransformBounds(BRect bounds) const
|
||||||
{
|
{
|
||||||
@@ -253,10 +231,10 @@ Transformable::TransformBounds(BRect bounds) const
|
|||||||
BPoint lb(bounds.left, bounds.bottom);
|
BPoint lb(bounds.left, bounds.bottom);
|
||||||
BPoint rb(bounds.right, bounds.bottom);
|
BPoint rb(bounds.right, bounds.bottom);
|
||||||
|
|
||||||
Transform(<);
|
StyleTransformer::Transform(<);
|
||||||
Transform(&rt);
|
StyleTransformer::Transform(&rt);
|
||||||
Transform(&lb);
|
StyleTransformer::Transform(&lb);
|
||||||
Transform(&rb);
|
StyleTransformer::Transform(&rb);
|
||||||
|
|
||||||
return BRect(floorf(min4(lt.x, rt.x, lb.x, rb.x)),
|
return BRect(floorf(min4(lt.x, rt.x, lb.x, rb.x)),
|
||||||
floorf(min4(lt.y, rt.y, lb.y, rb.y)),
|
floorf(min4(lt.y, rt.y, lb.y, rb.y)),
|
||||||
@@ -266,7 +244,7 @@ Transformable::TransformBounds(BRect bounds) const
|
|||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TranslateBy
|
|
||||||
void
|
void
|
||||||
Transformable::TranslateBy(BPoint offset)
|
Transformable::TranslateBy(BPoint offset)
|
||||||
{
|
{
|
||||||
@@ -276,7 +254,7 @@ Transformable::TranslateBy(BPoint offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RotateBy
|
|
||||||
void
|
void
|
||||||
Transformable::RotateBy(BPoint origin, double degrees)
|
Transformable::RotateBy(BPoint origin, double degrees)
|
||||||
{
|
{
|
||||||
@@ -288,7 +266,7 @@ Transformable::RotateBy(BPoint origin, double degrees)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScaleBy
|
|
||||||
void
|
void
|
||||||
Transformable::ScaleBy(BPoint origin, double xScale, double yScale)
|
Transformable::ScaleBy(BPoint origin, double xScale, double yScale)
|
||||||
{
|
{
|
||||||
@@ -300,7 +278,7 @@ Transformable::ScaleBy(BPoint origin, double xScale, double yScale)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShearBy
|
|
||||||
void
|
void
|
||||||
Transformable::ShearBy(BPoint origin, double xShear, double yShear)
|
Transformable::ShearBy(BPoint origin, double xShear, double yShear)
|
||||||
{
|
{
|
||||||
@@ -312,7 +290,7 @@ Transformable::ShearBy(BPoint origin, double xShear, double yShear)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransformationChanged
|
|
||||||
void
|
void
|
||||||
Transformable::TransformationChanged()
|
Transformable::TransformationChanged()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006, Haiku.
|
* Copyright 2006, 2023, Haiku.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Stephan Aßmus <superstippi@gmx.de>
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TRANSFORMABLE_H
|
#ifndef TRANSFORMABLE_H
|
||||||
@@ -14,12 +15,17 @@
|
|||||||
#include <agg_trans_affine.h>
|
#include <agg_trans_affine.h>
|
||||||
|
|
||||||
#include "IconBuild.h"
|
#include "IconBuild.h"
|
||||||
|
#include "StyleTransformer.h"
|
||||||
|
#include "Transformer.h"
|
||||||
|
|
||||||
|
|
||||||
_BEGIN_ICON_NAMESPACE
|
_BEGIN_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
class Transformable : public agg::trans_affine {
|
/*! The standard affine transformation. */
|
||||||
|
// TODO: combine with AffineTransformer
|
||||||
|
class Transformable : public StyleTransformer,
|
||||||
|
public agg::trans_affine {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
matrix_size = 6,
|
matrix_size = 6,
|
||||||
@@ -29,6 +35,18 @@ class Transformable : public agg::trans_affine {
|
|||||||
Transformable(const Transformable& other);
|
Transformable(const Transformable& other);
|
||||||
virtual ~Transformable();
|
virtual ~Transformable();
|
||||||
|
|
||||||
|
// StyleTransformer interface
|
||||||
|
virtual void transform(double* x, double* y) const
|
||||||
|
{ return agg::trans_affine::transform(x, y); }
|
||||||
|
virtual void Invert();
|
||||||
|
virtual bool IsLinear()
|
||||||
|
{ return true; }
|
||||||
|
|
||||||
|
// Transformable
|
||||||
|
void InverseTransform(double* x, double* y) const;
|
||||||
|
void InverseTransform(BPoint* point) const;
|
||||||
|
BPoint InverseTransform(const BPoint& point) const;
|
||||||
|
|
||||||
void StoreTo(double matrix[matrix_size]) const;
|
void StoreTo(double matrix[matrix_size]) const;
|
||||||
void LoadFrom(const double matrix[matrix_size]);
|
void LoadFrom(const double matrix[matrix_size]);
|
||||||
|
|
||||||
@@ -38,8 +56,6 @@ class Transformable : public agg::trans_affine {
|
|||||||
Transformable& Multiply(const Transformable& other);
|
Transformable& Multiply(const Transformable& other);
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
|
|
||||||
void Invert();
|
|
||||||
|
|
||||||
bool IsIdentity() const;
|
bool IsIdentity() const;
|
||||||
bool IsTranslationOnly() const;
|
bool IsTranslationOnly() const;
|
||||||
bool IsNotDistorted() const;
|
bool IsNotDistorted() const;
|
||||||
@@ -48,15 +64,6 @@ class Transformable : public agg::trans_affine {
|
|||||||
bool operator==(const Transformable& other) const;
|
bool operator==(const Transformable& other) const;
|
||||||
bool operator!=(const Transformable& other) const;
|
bool operator!=(const Transformable& other) const;
|
||||||
|
|
||||||
// transforms coordiantes
|
|
||||||
void Transform(double* x, double* y) const;
|
|
||||||
void Transform(BPoint* point) const;
|
|
||||||
BPoint Transform(const BPoint& point) const;
|
|
||||||
|
|
||||||
void InverseTransform(double* x, double* y) const;
|
|
||||||
void InverseTransform(BPoint* point) const;
|
|
||||||
BPoint InverseTransform(const BPoint& point) const;
|
|
||||||
|
|
||||||
// transforms the rectangle "bounds" and
|
// transforms the rectangle "bounds" and
|
||||||
// returns the *bounding box* of that
|
// returns the *bounding box* of that
|
||||||
BRect TransformBounds(BRect bounds) const;
|
BRect TransformBounds(BRect bounds) const;
|
||||||
@@ -70,7 +77,7 @@ class Transformable : public agg::trans_affine {
|
|||||||
virtual void TransformationChanged();
|
virtual void TransformationChanged();
|
||||||
// hook function that is called when the transformation
|
// hook function that is called when the transformation
|
||||||
// is changed for some reason
|
// is changed for some reason
|
||||||
|
|
||||||
virtual void PrintToStream() const;
|
virtual void PrintToStream() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -82,4 +89,3 @@ _USING_ICON_NAMESPACE
|
|||||||
|
|
||||||
|
|
||||||
#endif // TRANSFORMABLE_H
|
#endif // TRANSFORMABLE_H
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ using std::nothrow;
|
|||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
AffineTransformer::AffineTransformer(VertexSource& source)
|
AffineTransformer::AffineTransformer(VertexSource& source)
|
||||||
: Transformer(source, "Transformation"),
|
: Transformer("Transformation"),
|
||||||
|
PathTransformer(source),
|
||||||
Affine(source, *this)
|
Affine(source, *this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -34,7 +35,8 @@ AffineTransformer::AffineTransformer(VertexSource& source)
|
|||||||
// constructor
|
// constructor
|
||||||
AffineTransformer::AffineTransformer(VertexSource& source,
|
AffineTransformer::AffineTransformer(VertexSource& source,
|
||||||
BMessage* archive)
|
BMessage* archive)
|
||||||
: Transformer(source, archive),
|
: Transformer(archive),
|
||||||
|
PathTransformer(source),
|
||||||
Affine(source, *this)
|
Affine(source, *this)
|
||||||
{
|
{
|
||||||
if (!archive)
|
if (!archive)
|
||||||
@@ -57,9 +59,9 @@ AffineTransformer::~AffineTransformer()
|
|||||||
|
|
||||||
// Clone
|
// Clone
|
||||||
Transformer*
|
Transformer*
|
||||||
AffineTransformer::Clone(VertexSource& source) const
|
AffineTransformer::Clone() const
|
||||||
{
|
{
|
||||||
AffineTransformer* clone = new (nothrow) AffineTransformer(source);
|
AffineTransformer* clone = new (nothrow) AffineTransformer(fSource);
|
||||||
if (clone)
|
if (clone)
|
||||||
clone->multiply(*this);
|
clone->multiply(*this);
|
||||||
return clone;
|
return clone;
|
||||||
@@ -83,7 +85,7 @@ AffineTransformer::vertex(double* x, double* y)
|
|||||||
void
|
void
|
||||||
AffineTransformer::SetSource(VertexSource& source)
|
AffineTransformer::SetSource(VertexSource& source)
|
||||||
{
|
{
|
||||||
Transformer::SetSource(source);
|
PathTransformer::SetSource(source);
|
||||||
Affine::attach(source);
|
Affine::attach(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "IconBuild.h"
|
#include "IconBuild.h"
|
||||||
|
#include "PathTransformer.h"
|
||||||
#include "Transformer.h"
|
#include "Transformer.h"
|
||||||
|
|
||||||
#include <agg_conv_transform.h>
|
#include <agg_conv_transform.h>
|
||||||
@@ -23,6 +24,7 @@ typedef agg::conv_transform<VertexSource,
|
|||||||
agg::trans_affine> Affine;
|
agg::trans_affine> Affine;
|
||||||
|
|
||||||
class AffineTransformer : public Transformer,
|
class AffineTransformer : public Transformer,
|
||||||
|
public PathTransformer,
|
||||||
public Affine,
|
public Affine,
|
||||||
public agg::trans_affine {
|
public agg::trans_affine {
|
||||||
public:
|
public:
|
||||||
@@ -38,8 +40,10 @@ class AffineTransformer : public Transformer,
|
|||||||
|
|
||||||
virtual ~AffineTransformer();
|
virtual ~AffineTransformer();
|
||||||
|
|
||||||
virtual Transformer* Clone(VertexSource& source) const;
|
// Transformer interface
|
||||||
|
virtual Transformer* Clone() const;
|
||||||
|
|
||||||
|
// PathTransformer interface
|
||||||
virtual void rewind(unsigned path_id);
|
virtual void rewind(unsigned path_id);
|
||||||
virtual unsigned vertex(double* x, double* y);
|
virtual unsigned vertex(double* x, double* y);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "CompoundStyleTransformer.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
_USING_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
CompoundStyleTransformer::CompoundStyleTransformer(
|
||||||
|
StyleTransformer** transformers, int32 count)
|
||||||
|
:
|
||||||
|
fTransformers(transformers),
|
||||||
|
fCount(count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CompoundStyleTransformer::~CompoundStyleTransformer()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < fCount; i++)
|
||||||
|
delete fTransformers[i];
|
||||||
|
delete[] fTransformers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CompoundStyleTransformer::transform(double* x, double* y) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < fCount; i++) {
|
||||||
|
if (fTransformers[i] != NULL)
|
||||||
|
fTransformers[i]->transform(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CompoundStyleTransformer::Invert()
|
||||||
|
{
|
||||||
|
// reverse order of pipeline
|
||||||
|
StyleTransformer* oldOrder[fCount];
|
||||||
|
memcpy(oldOrder, fTransformers, fCount * sizeof(StyleTransformer*));
|
||||||
|
for (int i = 0; i < fCount; i++) {
|
||||||
|
fTransformers[fCount-i-1] = oldOrder[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// invert individual transformations
|
||||||
|
for (int i = 0; i < fCount; i++) {
|
||||||
|
if (fTransformers[i] != NULL)
|
||||||
|
fTransformers[i]->Invert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
CompoundStyleTransformer::IsLinear()
|
||||||
|
{
|
||||||
|
bool linear = true;
|
||||||
|
for (int i = 0; i < fCount; i++) {
|
||||||
|
if (fTransformers[i] != NULL)
|
||||||
|
linear &= fTransformers[i]->IsLinear();
|
||||||
|
}
|
||||||
|
return linear;
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
#ifndef COMPOUND_STYLE_TRANSFORMER_H
|
||||||
|
#define COMPOUND_STYLE_TRANSFORMER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include "IconBuild.h"
|
||||||
|
#include "StyleTransformer.h"
|
||||||
|
|
||||||
|
|
||||||
|
_BEGIN_ICON_NAMESPACE
|
||||||
|
|
||||||
|
class VertexSource;
|
||||||
|
class StyleTransformer;
|
||||||
|
|
||||||
|
|
||||||
|
/*! Allows turning an array of StyleTransformers into a single StyleTransformer.
|
||||||
|
|
||||||
|
\note This class is not meant to be exposed to the GUI or saved in a file. It
|
||||||
|
is currently only used for rendering.
|
||||||
|
*/
|
||||||
|
class CompoundStyleTransformer : public StyleTransformer {
|
||||||
|
public:
|
||||||
|
CompoundStyleTransformer(
|
||||||
|
StyleTransformer** transformers,
|
||||||
|
int32 count);
|
||||||
|
virtual ~CompoundStyleTransformer();
|
||||||
|
|
||||||
|
// StyleTransformer interface
|
||||||
|
virtual void transform(double* x, double* y) const;
|
||||||
|
virtual void Invert();
|
||||||
|
|
||||||
|
virtual bool IsLinear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
StyleTransformer** fTransformers;
|
||||||
|
int32 fCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
_END_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
#endif // COMPOUND_STYLE_TRANSFORMER_H
|
||||||
@@ -27,7 +27,8 @@ using std::nothrow;
|
|||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
ContourTransformer::ContourTransformer(VertexSource& source)
|
ContourTransformer::ContourTransformer(VertexSource& source)
|
||||||
: Transformer(source, "Contour"),
|
: Transformer("Contour"),
|
||||||
|
PathTransformer(source),
|
||||||
Contour(source)
|
Contour(source)
|
||||||
{
|
{
|
||||||
auto_detect_orientation(true);
|
auto_detect_orientation(true);
|
||||||
@@ -36,7 +37,8 @@ ContourTransformer::ContourTransformer(VertexSource& source)
|
|||||||
// constructor
|
// constructor
|
||||||
ContourTransformer::ContourTransformer(VertexSource& source,
|
ContourTransformer::ContourTransformer(VertexSource& source,
|
||||||
BMessage* archive)
|
BMessage* archive)
|
||||||
: Transformer(source, archive),
|
: Transformer(archive),
|
||||||
|
PathTransformer(source),
|
||||||
Contour(source)
|
Contour(source)
|
||||||
{
|
{
|
||||||
auto_detect_orientation(true);
|
auto_detect_orientation(true);
|
||||||
@@ -69,9 +71,9 @@ ContourTransformer::~ContourTransformer()
|
|||||||
|
|
||||||
// Clone
|
// Clone
|
||||||
Transformer*
|
Transformer*
|
||||||
ContourTransformer::Clone(VertexSource& source) const
|
ContourTransformer::Clone() const
|
||||||
{
|
{
|
||||||
ContourTransformer* clone = new (nothrow) ContourTransformer(source);
|
ContourTransformer* clone = new (nothrow) ContourTransformer(fSource);
|
||||||
if (clone) {
|
if (clone) {
|
||||||
clone->line_join(line_join());
|
clone->line_join(line_join());
|
||||||
clone->inner_join(inner_join());
|
clone->inner_join(inner_join());
|
||||||
@@ -101,7 +103,7 @@ ContourTransformer::vertex(double* x, double* y)
|
|||||||
void
|
void
|
||||||
ContourTransformer::SetSource(VertexSource& source)
|
ContourTransformer::SetSource(VertexSource& source)
|
||||||
{
|
{
|
||||||
Transformer::SetSource(source);
|
PathTransformer::SetSource(source);
|
||||||
Contour::attach(source);
|
Contour::attach(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "IconBuild.h"
|
#include "IconBuild.h"
|
||||||
|
#include "PathTransformer.h"
|
||||||
#include "Transformer.h"
|
#include "Transformer.h"
|
||||||
|
|
||||||
#include <agg_conv_contour.h>
|
#include <agg_conv_contour.h>
|
||||||
@@ -21,6 +22,7 @@ _BEGIN_ICON_NAMESPACE
|
|||||||
typedef agg::conv_contour<VertexSource> Contour;
|
typedef agg::conv_contour<VertexSource> Contour;
|
||||||
|
|
||||||
class ContourTransformer : public Transformer,
|
class ContourTransformer : public Transformer,
|
||||||
|
public PathTransformer,
|
||||||
public Contour {
|
public Contour {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
@@ -35,10 +37,12 @@ class ContourTransformer : public Transformer,
|
|||||||
|
|
||||||
virtual ~ContourTransformer();
|
virtual ~ContourTransformer();
|
||||||
|
|
||||||
virtual Transformer* Clone(VertexSource& source) const;
|
// Transformer interface
|
||||||
|
virtual Transformer* Clone() const;
|
||||||
|
|
||||||
|
// PathTransformer interface
|
||||||
virtual void rewind(unsigned path_id);
|
virtual void rewind(unsigned path_id);
|
||||||
virtual unsigned vertex(double* x, double* y);
|
virtual unsigned vertex(double* x, double* y);
|
||||||
|
|
||||||
virtual void SetSource(VertexSource& source);
|
virtual void SetSource(VertexSource& source);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2007, 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
#ifndef PATH_TRANSFORMER_H
|
||||||
|
#define PATH_TRANSFORMER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "IconBuild.h"
|
||||||
|
#include "VertexSource.h"
|
||||||
|
|
||||||
|
|
||||||
|
_BEGIN_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
/*! A transformation to a VertexSource.
|
||||||
|
It can add points, move them around, turn them to curves, etc.
|
||||||
|
*/
|
||||||
|
class PathTransformer : public VertexSource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PathTransformer(VertexSource& source)
|
||||||
|
: fSource(source) {}
|
||||||
|
virtual ~PathTransformer() {}
|
||||||
|
|
||||||
|
// PathTransformer
|
||||||
|
virtual void rewind(unsigned path_id)
|
||||||
|
{ fSource.rewind(path_id); }
|
||||||
|
virtual unsigned vertex(double* x, double* y)
|
||||||
|
{ return fSource.vertex(x, y); }
|
||||||
|
|
||||||
|
virtual void SetSource(VertexSource& source)
|
||||||
|
{ fSource = source; }
|
||||||
|
|
||||||
|
virtual bool WantsOpenPaths() const
|
||||||
|
{ return fSource.WantsOpenPaths(); }
|
||||||
|
virtual double ApproximationScale() const
|
||||||
|
{ return fSource.ApproximationScale(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
VertexSource& fSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
_END_ICON_NAMESPACE
|
||||||
|
|
||||||
|
#endif // PATH_TRANSFORMER_H
|
||||||
@@ -1,108 +1,341 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2007, Haiku.
|
* Copyright 2006-2007, 2023, Haiku.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Stephan Aßmus <superstippi@gmx.de>
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "PerspectiveTransformer.h"
|
#include "PerspectiveTransformer.h"
|
||||||
|
|
||||||
#ifdef ICON_O_MATIC
|
|
||||||
# include <Message.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <agg_basics.h>
|
||||||
|
#include <agg_bounding_rect.h>
|
||||||
|
#include <Message.h>
|
||||||
|
|
||||||
|
#include "Shape.h"
|
||||||
|
|
||||||
|
|
||||||
_USING_ICON_NAMESPACE
|
_USING_ICON_NAMESPACE
|
||||||
using std::nothrow;
|
using std::nothrow;
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
PerspectiveTransformer::PerspectiveTransformer(VertexSource& source, Shape* shape)
|
||||||
PerspectiveTransformer::PerspectiveTransformer(VertexSource& source)
|
: Transformer("Perspective"),
|
||||||
: Transformer(source, "Perspective"),
|
PathTransformer(source),
|
||||||
Perspective(source, *this)
|
Perspective(source, *this),
|
||||||
|
fShape(shape)
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
, fInverted(false)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
if (fShape != NULL) {
|
||||||
|
fShape->AcquireReference();
|
||||||
|
fShape->AddObserver(this);
|
||||||
|
ObjectChanged(fShape); // finish initialization
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// constructor
|
|
||||||
PerspectiveTransformer::PerspectiveTransformer(VertexSource& source,
|
PerspectiveTransformer::PerspectiveTransformer(
|
||||||
BMessage* archive)
|
VertexSource& source, Shape* shape, BMessage* archive)
|
||||||
: Transformer(source, archive),
|
: Transformer(archive),
|
||||||
Perspective(source, *this)
|
PathTransformer(source),
|
||||||
|
Perspective(source, *this),
|
||||||
|
fShape(shape)
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
, fInverted(false)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// TODO: upgrade AGG to be able to use load_from() etc
|
double matrix[9];
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
if (archive->FindDouble("matrix", i, &matrix[i]) != B_OK)
|
||||||
|
matrix[i] = 0;
|
||||||
|
}
|
||||||
|
load_from(matrix);
|
||||||
|
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
if (fShape != NULL) {
|
||||||
|
fShape->AcquireReference();
|
||||||
|
fShape->AddObserver(this);
|
||||||
|
ObjectChanged(fShape); // finish initialization
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
|
||||||
|
PerspectiveTransformer::PerspectiveTransformer(const PerspectiveTransformer& other)
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
: Transformer(other.Name()),
|
||||||
|
#else
|
||||||
|
: Transformer(""),
|
||||||
|
#endif
|
||||||
|
PathTransformer(other.fSource),
|
||||||
|
Perspective(fSource, *this),
|
||||||
|
fShape(other.fShape)
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
, fInverted(other.fInverted),
|
||||||
|
fFromBox(other.fFromBox),
|
||||||
|
fToLeftTop(other.fToLeftTop),
|
||||||
|
fToRightTop(other.fToRightTop),
|
||||||
|
fToLeftBottom(other.fToLeftBottom),
|
||||||
|
fToRightBottom(other.fToRightBottom),
|
||||||
|
fValid(other.fValid)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
double matrix[9];
|
||||||
|
other.store_to(matrix);
|
||||||
|
load_from(matrix);
|
||||||
|
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
if (fShape != NULL) {
|
||||||
|
fShape->AcquireReference();
|
||||||
|
fShape->AddObserver(this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PerspectiveTransformer::~PerspectiveTransformer()
|
PerspectiveTransformer::~PerspectiveTransformer()
|
||||||
{
|
{
|
||||||
}
|
#ifdef ICON_O_MATIC
|
||||||
|
if (fShape != NULL) {
|
||||||
// Clone
|
fShape->RemoveObserver(this);
|
||||||
Transformer*
|
fShape->ReleaseReference();
|
||||||
PerspectiveTransformer::Clone(VertexSource& source) const
|
|
||||||
{
|
|
||||||
PerspectiveTransformer* clone
|
|
||||||
= new (nothrow) PerspectiveTransformer(source);
|
|
||||||
if (clone) {
|
|
||||||
// TODO: upgrade AGG
|
|
||||||
// clone->multiply(*this);
|
|
||||||
}
|
}
|
||||||
return clone;
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// rewind
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
Transformer*
|
||||||
|
PerspectiveTransformer::Clone() const
|
||||||
|
{
|
||||||
|
return new (nothrow) PerspectiveTransformer(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PerspectiveTransformer::rewind(unsigned path_id)
|
PerspectiveTransformer::rewind(unsigned path_id)
|
||||||
{
|
{
|
||||||
Perspective::rewind(path_id);
|
Perspective::rewind(path_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// vertex
|
|
||||||
unsigned
|
unsigned
|
||||||
PerspectiveTransformer::vertex(double* x, double* y)
|
PerspectiveTransformer::vertex(double* x, double* y)
|
||||||
{
|
{
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
if (fValid)
|
||||||
|
return Perspective::vertex(x, y);
|
||||||
|
else
|
||||||
|
return agg::path_cmd_stop;
|
||||||
|
#else
|
||||||
return Perspective::vertex(x, y);
|
return Perspective::vertex(x, y);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSource
|
|
||||||
void
|
void
|
||||||
PerspectiveTransformer::SetSource(VertexSource& source)
|
PerspectiveTransformer::SetSource(VertexSource& source)
|
||||||
{
|
{
|
||||||
Transformer::SetSource(source);
|
PathTransformer::SetSource(source);
|
||||||
Perspective::attach(source);
|
Perspective::attach(source);
|
||||||
|
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
ObjectChanged(fShape);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApproximationScale
|
|
||||||
double
|
double
|
||||||
PerspectiveTransformer::ApproximationScale() const
|
PerspectiveTransformer::ApproximationScale() const
|
||||||
{
|
{
|
||||||
// TODO: upgrade AGG
|
return fSource.ApproximationScale() * scale();
|
||||||
return fSource.ApproximationScale();// * scale();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveTransformer::Invert()
|
||||||
|
{
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
fInverted = !fInverted;
|
||||||
|
|
||||||
|
// TODO: degenerate matrices may not be adequately handled
|
||||||
|
bool degenerate = !invert();
|
||||||
|
fValid = fValid && !degenerate;
|
||||||
|
#else
|
||||||
|
invert();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
#ifdef ICON_O_MATIC
|
#ifdef ICON_O_MATIC
|
||||||
|
|
||||||
// Archive
|
|
||||||
status_t
|
status_t
|
||||||
PerspectiveTransformer::Archive(BMessage* into, bool deep) const
|
PerspectiveTransformer::Archive(BMessage* into, bool deep) const
|
||||||
{
|
{
|
||||||
status_t ret = Transformer::Archive(into, deep);
|
status_t ret = Transformer::Archive(into, deep);
|
||||||
|
|
||||||
if (ret == B_OK)
|
into->what = archive_code;
|
||||||
into->what = archive_code;
|
|
||||||
|
|
||||||
// TODO: upgrade AGG to be able to use store_to()
|
double matrix[9];
|
||||||
|
store_to(matrix);
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
if (ret == B_OK)
|
||||||
|
ret = into->AddDouble("matrix", matrix[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #prama mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveTransformer::ObjectChanged(const Observable* object)
|
||||||
|
{
|
||||||
|
if (fInverted) {
|
||||||
|
printf("calculating the validity or bounding box of an inverted "
|
||||||
|
"perspective transformer is currently unsupported.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 pathID[1];
|
||||||
|
pathID[0] = 0;
|
||||||
|
double left, top, right, bottom;
|
||||||
|
agg::bounding_rect(fSource, pathID, 0, 1, &left, &top, &right, &bottom);
|
||||||
|
BRect newFromBox = BRect(left, top, right, bottom);
|
||||||
|
|
||||||
|
// Stop if nothing we care about has changed
|
||||||
|
// TODO: Can this be done earlier? It would be nice to avoid having to
|
||||||
|
// recalculate the bounding box before realizing nothing needs to be done.
|
||||||
|
if (fFromBox == newFromBox)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fFromBox = newFromBox;
|
||||||
|
|
||||||
|
_CheckValidity();
|
||||||
|
|
||||||
|
double x = fFromBox.left; double y = fFromBox.top;
|
||||||
|
Transform(&x, &y);
|
||||||
|
fToLeftTop = BPoint(x, y);
|
||||||
|
|
||||||
|
x = fFromBox.right; y = fFromBox.top;
|
||||||
|
Transform(&x, &y);
|
||||||
|
fToRightTop = BPoint(x, y);
|
||||||
|
|
||||||
|
x = fFromBox.left; y = fFromBox.bottom;
|
||||||
|
Transform(&x, &y);
|
||||||
|
fToLeftBottom = BPoint(x, y);
|
||||||
|
|
||||||
|
x = fFromBox.right; y = fFromBox.bottom;
|
||||||
|
Transform(&x, &y);
|
||||||
|
fToRightBottom = BPoint(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveTransformer::TransformTo(
|
||||||
|
BPoint leftTop, BPoint rightTop, BPoint leftBottom, BPoint rightBottom)
|
||||||
|
{
|
||||||
|
fToLeftTop = leftTop;
|
||||||
|
fToRightTop = rightTop;
|
||||||
|
fToLeftBottom = leftBottom;
|
||||||
|
fToRightBottom = rightBottom;
|
||||||
|
|
||||||
|
double quad[8] = {
|
||||||
|
fToLeftTop.x, fToLeftTop.y,
|
||||||
|
fToRightTop.x, fToRightTop.y,
|
||||||
|
fToRightBottom.x, fToRightBottom.y,
|
||||||
|
fToLeftBottom.x, fToLeftBottom.y
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!fInverted) {
|
||||||
|
rect_to_quad(
|
||||||
|
fFromBox.left, fFromBox.top,
|
||||||
|
fFromBox.right, fFromBox.bottom, quad);
|
||||||
|
} else {
|
||||||
|
quad_to_rect(quad,
|
||||||
|
fFromBox.left, fFromBox.top,
|
||||||
|
fFromBox.right, fFromBox.bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
_CheckValidity();
|
||||||
|
Notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PerspectiveTransformer::_CheckValidity()
|
||||||
|
{
|
||||||
|
// Checks that none of the points are too close to the camera. These tend to
|
||||||
|
// lead to very big numbers or a divide by zero error. Also checks that all
|
||||||
|
// points are on the same side of the camera. Transformations with points on
|
||||||
|
// different sides of the camera look weird and tend to cause crashes.
|
||||||
|
|
||||||
|
fValid = true;
|
||||||
|
double w;
|
||||||
|
bool positive;
|
||||||
|
|
||||||
|
if (!fInverted) {
|
||||||
|
w = fFromBox.left * w0 + fFromBox.top * w1 + w2;
|
||||||
|
fValid &= (fabs(w) > 0.00001);
|
||||||
|
positive = w > 0;
|
||||||
|
|
||||||
|
w = fFromBox.right * w0 + fFromBox.top * w1 + w2;
|
||||||
|
fValid &= (fabs(w) > 0.00001);
|
||||||
|
fValid &= (w>0)==positive;
|
||||||
|
|
||||||
|
w = fFromBox.left * w0 + fFromBox.bottom * w1 + w2;
|
||||||
|
fValid &= (fabs(w) > 0.00001);
|
||||||
|
fValid &= (w>0)==positive;
|
||||||
|
|
||||||
|
w = fFromBox.right * w0 + fFromBox.bottom * w1 + w2;
|
||||||
|
fValid &= (fabs(w) > 0.00001);
|
||||||
|
fValid &= (w>0)==positive;
|
||||||
|
} else {
|
||||||
|
w = fToLeftTop.x * w0 + fToLeftTop.y * w1 + w2;
|
||||||
|
fValid &= (fabs(w) > 0.00001);
|
||||||
|
positive = w > 0;
|
||||||
|
|
||||||
|
w = fToRightTop.x * w0 + fToRightTop.y * w1 + w2;
|
||||||
|
fValid &= (fabs(w) > 0.00001);
|
||||||
|
fValid &= (w>0)==positive;
|
||||||
|
|
||||||
|
w = fToLeftBottom.x * w0 + fToLeftBottom.y * w1 + w2;
|
||||||
|
fValid &= (fabs(w) > 0.00001);
|
||||||
|
fValid &= (w>0)==positive;
|
||||||
|
|
||||||
|
w = fToRightBottom.x * w0 + fToRightBottom.y * w1 + w2;
|
||||||
|
fValid &= (fabs(w) > 0.00001);
|
||||||
|
fValid &= (w>0)==positive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ICON_O_MATIC
|
#endif // ICON_O_MATIC
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +1,76 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2007, Haiku.
|
* Copyright 2006-2007, 2023, Haiku.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Stephan Aßmus <superstippi@gmx.de>
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
*/
|
*/
|
||||||
#ifndef PERSPECTIVE_TRANSFORMER_H
|
#ifndef PERSPECTIVE_TRANSFORMER_H
|
||||||
#define PERSPECTIVE_TRANSFORMER_H
|
#define PERSPECTIVE_TRANSFORMER_H
|
||||||
|
|
||||||
|
|
||||||
#include "IconBuild.h"
|
#include <Rect.h>
|
||||||
#include "Transformer.h"
|
#include <Point.h>
|
||||||
|
|
||||||
#include <agg_conv_transform.h>
|
#include <agg_conv_transform.h>
|
||||||
#include <agg_trans_perspective.h>
|
#include <agg_trans_perspective.h>
|
||||||
|
|
||||||
|
#include "IconBuild.h"
|
||||||
|
#include "Transformer.h"
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
#include "Observer.h"
|
||||||
|
#endif
|
||||||
|
#include "PathTransformer.h"
|
||||||
|
#include "StyleTransformer.h"
|
||||||
|
#include "VertexSource.h"
|
||||||
|
|
||||||
|
|
||||||
_BEGIN_ICON_NAMESPACE
|
_BEGIN_ICON_NAMESPACE
|
||||||
|
|
||||||
|
class Shape;
|
||||||
|
|
||||||
typedef agg::conv_transform<VertexSource,
|
|
||||||
agg::trans_perspective> Perspective;
|
|
||||||
|
|
||||||
|
typedef agg::conv_transform<VertexSource, agg::trans_perspective> Perspective;
|
||||||
|
|
||||||
|
/*! Transforms from the VertexSource's bounding rect to the specified
|
||||||
|
quadrilateral. This class watches out for invalid transformations if
|
||||||
|
\c ICON_O_MATIC is set.
|
||||||
|
*/
|
||||||
class PerspectiveTransformer : public Transformer,
|
class PerspectiveTransformer : public Transformer,
|
||||||
|
public PathTransformer,
|
||||||
|
public StyleTransformer,
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
public Observer,
|
||||||
|
#endif
|
||||||
public Perspective,
|
public Perspective,
|
||||||
public agg::trans_perspective {
|
public agg::trans_perspective {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
archive_code = 'prsp',
|
archive_code = 'prsp',
|
||||||
};
|
};
|
||||||
|
|
||||||
PerspectiveTransformer(
|
/*! Initializes starting with the identity transformation.
|
||||||
VertexSource& source);
|
A valid perspective transformation can be rendered invalid if the shape
|
||||||
|
changes. Listens to \a shape for updates and determines if the
|
||||||
|
transformation is still valid if \c ICON_O_MATIC is set.
|
||||||
|
*/
|
||||||
PerspectiveTransformer(
|
PerspectiveTransformer(
|
||||||
VertexSource& source,
|
VertexSource& source,
|
||||||
|
Shape* shape);
|
||||||
|
PerspectiveTransformer(
|
||||||
|
VertexSource& source,
|
||||||
|
Shape* shape,
|
||||||
BMessage* archive);
|
BMessage* archive);
|
||||||
|
PerspectiveTransformer(
|
||||||
|
const PerspectiveTransformer& other);
|
||||||
|
|
||||||
virtual ~PerspectiveTransformer();
|
virtual ~PerspectiveTransformer();
|
||||||
|
|
||||||
// Transformer interface
|
// Transformer interface
|
||||||
virtual Transformer* Clone(VertexSource& source) const;
|
virtual Transformer* Clone() const;
|
||||||
|
|
||||||
|
// PathTransformer interface
|
||||||
virtual void rewind(unsigned path_id);
|
virtual void rewind(unsigned path_id);
|
||||||
virtual unsigned vertex(double* x, double* y);
|
virtual unsigned vertex(double* x, double* y);
|
||||||
|
|
||||||
@@ -48,11 +78,55 @@ class PerspectiveTransformer : public Transformer,
|
|||||||
|
|
||||||
virtual double ApproximationScale() const;
|
virtual double ApproximationScale() const;
|
||||||
|
|
||||||
|
// StyleTransformer interface
|
||||||
|
virtual void transform(double* x, double* y) const
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
{ if (fValid) agg::trans_perspective::transform(x, y); }
|
||||||
|
#else
|
||||||
|
{ agg::trans_perspective::transform(x, y); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! Inverts the perspective transformation.
|
||||||
|
\warning This class can mostly only transform points when inverted. Most
|
||||||
|
other features either have not been tested or are missing.
|
||||||
|
*/
|
||||||
|
virtual void Invert();
|
||||||
|
|
||||||
#ifdef ICON_O_MATIC
|
#ifdef ICON_O_MATIC
|
||||||
// IconObject interface
|
// IconObject interface
|
||||||
virtual status_t Archive(BMessage* into,
|
virtual status_t Archive(BMessage* into,
|
||||||
bool deep = true) const;
|
bool deep = true) const;
|
||||||
|
|
||||||
|
// Observer interface
|
||||||
|
virtual void ObjectChanged(const Observable* object);
|
||||||
|
|
||||||
|
// PerspectiveTransformer
|
||||||
|
void TransformTo(BPoint leftTop, BPoint rightTop,
|
||||||
|
BPoint leftBottom, BPoint rightBottom);
|
||||||
|
|
||||||
|
BPoint LeftTop()
|
||||||
|
{ return fToLeftTop; }
|
||||||
|
BPoint RightTop()
|
||||||
|
{ return fToRightTop; }
|
||||||
|
BPoint LeftBottom()
|
||||||
|
{ return fToLeftBottom; }
|
||||||
|
BPoint RightBottom()
|
||||||
|
{ return fToRightBottom; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _CheckValidity();
|
||||||
|
#endif // ICON_O_MATIC
|
||||||
|
|
||||||
|
private:
|
||||||
|
Shape* fShape;
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
bool fInverted;
|
||||||
|
BRect fFromBox;
|
||||||
|
BPoint fToLeftTop;
|
||||||
|
BPoint fToRightTop;
|
||||||
|
BPoint fToLeftBottom;
|
||||||
|
BPoint fToRightBottom;
|
||||||
|
bool fValid;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ using std::nothrow;
|
|||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
StrokeTransformer::StrokeTransformer(VertexSource& source)
|
StrokeTransformer::StrokeTransformer(VertexSource& source)
|
||||||
: Transformer(source, "Stroke"),
|
: Transformer("Stroke"),
|
||||||
|
PathTransformer(source),
|
||||||
Stroke(source)
|
Stroke(source)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -35,7 +36,8 @@ StrokeTransformer::StrokeTransformer(VertexSource& source)
|
|||||||
// constructor
|
// constructor
|
||||||
StrokeTransformer::StrokeTransformer(VertexSource& source,
|
StrokeTransformer::StrokeTransformer(VertexSource& source,
|
||||||
BMessage* archive)
|
BMessage* archive)
|
||||||
: Transformer(source, archive),
|
: Transformer(archive),
|
||||||
|
PathTransformer(source),
|
||||||
Stroke(source)
|
Stroke(source)
|
||||||
{
|
{
|
||||||
if (!archive)
|
if (!archive)
|
||||||
@@ -72,9 +74,9 @@ StrokeTransformer::~StrokeTransformer()
|
|||||||
|
|
||||||
// Clone
|
// Clone
|
||||||
Transformer*
|
Transformer*
|
||||||
StrokeTransformer::Clone(VertexSource& source) const
|
StrokeTransformer::Clone() const
|
||||||
{
|
{
|
||||||
StrokeTransformer* clone = new (nothrow) StrokeTransformer(source);
|
StrokeTransformer* clone = new (nothrow) StrokeTransformer(fSource);
|
||||||
if (clone) {
|
if (clone) {
|
||||||
clone->line_cap(line_cap());
|
clone->line_cap(line_cap());
|
||||||
clone->line_join(line_join());
|
clone->line_join(line_join());
|
||||||
@@ -105,7 +107,7 @@ StrokeTransformer::vertex(double* x, double* y)
|
|||||||
void
|
void
|
||||||
StrokeTransformer::SetSource(VertexSource& source)
|
StrokeTransformer::SetSource(VertexSource& source)
|
||||||
{
|
{
|
||||||
Transformer::SetSource(source);
|
PathTransformer::SetSource(source);
|
||||||
Stroke::attach(source);
|
Stroke::attach(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "IconBuild.h"
|
#include "IconBuild.h"
|
||||||
|
#include "PathTransformer.h"
|
||||||
#include "Transformer.h"
|
#include "Transformer.h"
|
||||||
|
|
||||||
#include <agg_conv_stroke.h>
|
#include <agg_conv_stroke.h>
|
||||||
@@ -21,6 +22,7 @@ _BEGIN_ICON_NAMESPACE
|
|||||||
typedef agg::conv_stroke<VertexSource> Stroke;
|
typedef agg::conv_stroke<VertexSource> Stroke;
|
||||||
|
|
||||||
class StrokeTransformer : public Transformer,
|
class StrokeTransformer : public Transformer,
|
||||||
|
public PathTransformer,
|
||||||
public Stroke {
|
public Stroke {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
@@ -36,8 +38,9 @@ class StrokeTransformer : public Transformer,
|
|||||||
virtual ~StrokeTransformer();
|
virtual ~StrokeTransformer();
|
||||||
|
|
||||||
// Transformer interface
|
// Transformer interface
|
||||||
virtual Transformer* Clone(VertexSource& source) const;
|
virtual Transformer* Clone() const;
|
||||||
|
|
||||||
|
// PathTransformer interface
|
||||||
virtual void rewind(unsigned path_id);
|
virtual void rewind(unsigned path_id);
|
||||||
virtual unsigned vertex(double* x, double* y);
|
virtual unsigned vertex(double* x, double* y);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StyleTransformer.h"
|
||||||
|
|
||||||
|
#include <Point.h>
|
||||||
|
|
||||||
|
|
||||||
|
_USING_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
StyleTransformer::~StyleTransformer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StyleTransformer::Transform(BPoint* point) const
|
||||||
|
{
|
||||||
|
if (point) {
|
||||||
|
double x = point->x;
|
||||||
|
double y = point->y;
|
||||||
|
|
||||||
|
Transform(&x, &y);
|
||||||
|
|
||||||
|
point->x = x;
|
||||||
|
point->y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BPoint
|
||||||
|
StyleTransformer::Transform(const BPoint& point) const
|
||||||
|
{
|
||||||
|
BPoint p(point);
|
||||||
|
Transform(&p);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Zardshard
|
||||||
|
*/
|
||||||
|
#ifndef STYLE_TRANSFORMER_H
|
||||||
|
#define STYLE_TRANSFORMER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "IconBuild.h"
|
||||||
|
|
||||||
|
|
||||||
|
class BPoint;
|
||||||
|
|
||||||
|
_BEGIN_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
/*! Warps a shape's style.
|
||||||
|
Implements the same interface as any other class of the agg:trans_ series.
|
||||||
|
This class can be used wherever AGG needs a transformer (for example,
|
||||||
|
agg::span_interpolator_linear<StyleTransformer> is valid).
|
||||||
|
*/
|
||||||
|
class StyleTransformer {
|
||||||
|
public:
|
||||||
|
StyleTransformer() {}
|
||||||
|
virtual ~StyleTransformer();
|
||||||
|
|
||||||
|
/*! Transform a single point of the shape's style.
|
||||||
|
This function should be fast since it will be called many times.
|
||||||
|
|
||||||
|
\note This function is lowercase so that it satisfies the role of an agg
|
||||||
|
transformer
|
||||||
|
*/
|
||||||
|
virtual void transform(double* x, double* y) const = 0;
|
||||||
|
|
||||||
|
/*! Alias of \c transform.
|
||||||
|
Use of this in our code is preffered because it follows the normal
|
||||||
|
capitalization scheme.
|
||||||
|
*/
|
||||||
|
void Transform(double* x, double* y) const
|
||||||
|
{ transform(x, y); }
|
||||||
|
void Transform(BPoint* point) const;
|
||||||
|
BPoint Transform(const BPoint& point) const;
|
||||||
|
|
||||||
|
virtual void Invert() = 0;
|
||||||
|
|
||||||
|
/*! Is the transformation a linear transformation?
|
||||||
|
This allows using linear interpolation instead of calling \c transform
|
||||||
|
for each point. */
|
||||||
|
virtual bool IsLinear()
|
||||||
|
{ return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
_END_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
#endif // STYLE_TRANSFORMER_H
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2007, Haiku.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Stephan Aßmus <superstippi@gmx.de>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "Transformer.h"
|
|
||||||
|
|
||||||
|
|
||||||
_USING_ICON_NAMESPACE
|
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
VertexSource::VertexSource()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
VertexSource::~VertexSource()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
Transformer::Transformer(VertexSource& source, const char* name)
|
|
||||||
#ifdef ICON_O_MATIC
|
|
||||||
: IconObject(name),
|
|
||||||
#else
|
|
||||||
:
|
|
||||||
#endif
|
|
||||||
fSource(source)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
Transformer::Transformer(VertexSource& source,
|
|
||||||
BMessage* archive)
|
|
||||||
#ifdef ICON_O_MATIC
|
|
||||||
: IconObject(archive),
|
|
||||||
#else
|
|
||||||
:
|
|
||||||
#endif
|
|
||||||
fSource(source)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
Transformer::~Transformer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
// rewind
|
|
||||||
void
|
|
||||||
Transformer::rewind(unsigned path_id)
|
|
||||||
{
|
|
||||||
fSource.rewind(path_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// vertex
|
|
||||||
unsigned
|
|
||||||
Transformer::vertex(double* x, double* y)
|
|
||||||
{
|
|
||||||
return fSource.vertex(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSource
|
|
||||||
void
|
|
||||||
Transformer::SetSource(VertexSource& source)
|
|
||||||
{
|
|
||||||
fSource = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
// WantsOpenPaths
|
|
||||||
bool
|
|
||||||
Transformer::WantsOpenPaths() const
|
|
||||||
{
|
|
||||||
return fSource.WantsOpenPaths();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApproximationScale
|
|
||||||
double
|
|
||||||
Transformer::ApproximationScale() const
|
|
||||||
{
|
|
||||||
return fSource.ApproximationScale();
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -17,52 +17,35 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "IconBuild.h"
|
#include "IconBuild.h"
|
||||||
|
#include "VertexSource.h"
|
||||||
|
|
||||||
|
|
||||||
_BEGIN_ICON_NAMESPACE
|
_BEGIN_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
class VertexSource {
|
/*! Base class for all transformers.
|
||||||
public:
|
All child classes should inherit either PathTransformer, StyleTransformer,
|
||||||
VertexSource();
|
or both.
|
||||||
virtual ~VertexSource();
|
*/
|
||||||
|
|
||||||
virtual void rewind(unsigned path_id) = 0;
|
|
||||||
virtual unsigned vertex(double* x, double* y) = 0;
|
|
||||||
|
|
||||||
/*! Determines whether open paths should be closed or left open. */
|
|
||||||
virtual bool WantsOpenPaths() const = 0;
|
|
||||||
virtual double ApproximationScale() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ICON_O_MATIC
|
#ifdef ICON_O_MATIC
|
||||||
class Transformer : public VertexSource,
|
class Transformer : public IconObject {
|
||||||
public IconObject {
|
|
||||||
#else
|
#else
|
||||||
class Transformer : public VertexSource {
|
class Transformer {
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
#ifdef ICON_O_MATIC
|
||||||
|
Transformer(const char* name)
|
||||||
|
: IconObject(name) {}
|
||||||
|
Transformer(BMessage* archive)
|
||||||
|
: IconObject(archive) {}
|
||||||
|
#else
|
||||||
|
Transformer(const char* name) {}
|
||||||
|
Transformer(BMessage* archive) {}
|
||||||
#endif
|
#endif
|
||||||
public:
|
|
||||||
Transformer(VertexSource& source,
|
|
||||||
const char* name);
|
|
||||||
Transformer(VertexSource& source,
|
|
||||||
BMessage* archive);
|
|
||||||
|
|
||||||
virtual ~Transformer();
|
virtual ~Transformer() {}
|
||||||
|
|
||||||
// Transformer
|
virtual Transformer* Clone() const = 0;
|
||||||
virtual Transformer* Clone(VertexSource& source) const = 0;
|
|
||||||
|
|
||||||
virtual void rewind(unsigned path_id);
|
|
||||||
virtual unsigned vertex(double* x, double* y);
|
|
||||||
|
|
||||||
virtual void SetSource(VertexSource& source);
|
|
||||||
|
|
||||||
virtual bool WantsOpenPaths() const;
|
|
||||||
virtual double ApproximationScale() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
VertexSource& fSource;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "AffineTransformer.h"
|
#include "AffineTransformer.h"
|
||||||
#include "ContourTransformer.h"
|
#include "ContourTransformer.h"
|
||||||
#include "PerspectiveTransformer.h"
|
#include "PerspectiveTransformer.h"
|
||||||
|
#include "Shape.h"
|
||||||
#include "StrokeTransformer.h"
|
#include "StrokeTransformer.h"
|
||||||
|
|
||||||
#ifdef ICON_O_MATIC
|
#ifdef ICON_O_MATIC
|
||||||
@@ -24,13 +25,13 @@ _USING_ICON_NAMESPACE
|
|||||||
|
|
||||||
// TransformerFor
|
// TransformerFor
|
||||||
Transformer*
|
Transformer*
|
||||||
TransformerFactory::TransformerFor(uint32 type, VertexSource& source)
|
TransformerFactory::TransformerFor(uint32 type, VertexSource& source, Shape* shape)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AFFINE_TRANSFORMER:
|
case AFFINE_TRANSFORMER:
|
||||||
return new AffineTransformer(source);
|
return new AffineTransformer(source);
|
||||||
case PERSPECTIVE_TRANSFORMER:
|
case PERSPECTIVE_TRANSFORMER:
|
||||||
return new PerspectiveTransformer(source);
|
return new PerspectiveTransformer(source, shape);
|
||||||
case CONTOUR_TRANSFORMER:
|
case CONTOUR_TRANSFORMER:
|
||||||
return new ContourTransformer(source);
|
return new ContourTransformer(source);
|
||||||
case STROKE_TRANSFORMER:
|
case STROKE_TRANSFORMER:
|
||||||
@@ -42,14 +43,13 @@ TransformerFactory::TransformerFor(uint32 type, VertexSource& source)
|
|||||||
|
|
||||||
// TransformerFor
|
// TransformerFor
|
||||||
Transformer*
|
Transformer*
|
||||||
TransformerFactory::TransformerFor(BMessage* message,
|
TransformerFactory::TransformerFor(BMessage* message, VertexSource& source, Shape* shape)
|
||||||
VertexSource& source)
|
|
||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case AffineTransformer::archive_code:
|
case AffineTransformer::archive_code:
|
||||||
return new AffineTransformer(source, message);
|
return new AffineTransformer(source, message);
|
||||||
case PerspectiveTransformer::archive_code:
|
case PerspectiveTransformer::archive_code:
|
||||||
return new PerspectiveTransformer(source, message);
|
return new PerspectiveTransformer(source, shape, message);
|
||||||
case ContourTransformer::archive_code:
|
case ContourTransformer::archive_code:
|
||||||
return new ContourTransformer(source, message);
|
return new ContourTransformer(source, message);
|
||||||
case StrokeTransformer::archive_code:
|
case StrokeTransformer::archive_code:
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class BMessage;
|
|||||||
_BEGIN_ICON_NAMESPACE
|
_BEGIN_ICON_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
class Shape;
|
||||||
class Transformer;
|
class Transformer;
|
||||||
class VertexSource;
|
class VertexSource;
|
||||||
|
|
||||||
@@ -35,10 +36,12 @@ class TransformerFactory {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
static Transformer* TransformerFor(uint32 type,
|
static Transformer* TransformerFor(uint32 type,
|
||||||
VertexSource& source);
|
VertexSource& source,
|
||||||
|
Shape* shape);
|
||||||
|
|
||||||
static Transformer* TransformerFor(BMessage* archive,
|
static Transformer* TransformerFor(BMessage* archive,
|
||||||
VertexSource& source);
|
VertexSource& source,
|
||||||
|
Shape* shape);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user