home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-25 | 21.2 KB | 683 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: DrawPrxy.cpp
- // Release Version: $ ODF 1 $
- //
- // Author: Henri Lamiraux
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "ODFDraw.hpp"
-
- #ifndef DRAWPRXY_H
- #include "DrawPrxy.h"
- #endif
-
- #ifndef DRAWPART_H
- #include "DrawPart.h"
- #endif
-
- #ifndef DRAWFRM_H
- #include "DrawFrm.h"
- #endif
-
- #ifndef BASESHP_H
- #include "BaseShp.h"
- #endif
-
- #ifndef BOUNDSHP_H
- #include "BoundShp.h"
- #endif
-
- #ifndef LINESHP_H
- #include "LineShp.h"
- #endif
-
- #ifndef OVALSHP_H
- #include "OvalShp.h"
- #endif
-
- #ifndef RECTSHP_H
- #include "RectShp.h"
- #endif
-
- #ifndef RRECTSHP_H
- #include "RRectShp.h"
- #endif
-
- #ifndef TEXTSHP_H
- #include "TextShp.h"
- #endif
-
- #ifndef DRAWCLIP_H
- #include "DrawClip.h"
- #endif
-
- #ifndef UTILS_H
- #include "Utils.h"
- #endif
-
- // ----- Part Layer -----
-
- #ifndef FWITERS_H
- #include "FWIters.h"
- #endif
-
- #ifndef FWPXYITE_H
- #include "FWPxyIte.h"
- #endif
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- #ifndef FWPART_H
- #include "FWPart.h"
- #endif
-
- #ifndef FWPRTITE_H
- #include "FWPrtIte.h"
- #endif
-
- #ifndef FWPRESEN_H
- #include "FWPresen.h"
- #endif
-
- #ifndef FWPXYFRM_H
- #include "FWPxyFrm.h"
- #endif
-
- // ----- OS Layer -----
-
- #ifndef FWRECT_H
- #include "FWRect.h"
- #endif
-
- #ifndef FWODGEOM_H
- #include "FWODGeom.h"
- #endif
-
- #ifndef FWEVENT_H
- #include "FWEvent.h"
- #endif
-
- // ----- Foundation Includes -----
-
- #ifndef FWSTREAM_H
- #include "FWStream.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_ODShape_xh
- #include <Shape.xh>
- #endif
-
- #ifndef SOM_ODTransform_xh
- #include <Trnsform.xh>
- #endif
-
- //========================================================================================
- // Runtime Information
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfdraw
- #endif
-
- FW_DEFINE_AUTO(CProxyShape)
- FW_DEFINE_CLASS_M1(CProxyShape, CRectShape)
-
- const FW_ClassTypeConstant LProxyShape = FW_TYPE_CONSTANT('s','h','p','x');
- FW_REGISTER_ARCHIVABLE_CLASS(LProxyShape, CProxyShape, CProxyShape::Read, 0, 0, CBaseShape::Write)
-
- //========================================================================================
- // CProxyShape
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::CProxyShape
- //----------------------------------------------------------------------------------------
-
- CProxyShape::CProxyShape(Environment* ev, const FW_CRect& rect, CDrawPart* drawPart) :
- CRectShape(kProxyShape, kFillOnly),
- FW_MProxy(ev, drawPart, drawPart->GetMainPresentation()),
- fDrawPart(drawPart),
- fFrozen(FALSE),
- fFrameRect(rect)
- {
- SetRectGeometry(rect);
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::CProxyShape
- //----------------------------------------------------------------------------------------
-
- CProxyShape::CProxyShape(Environment* ev, CDrawPart* drawPart, FW_CReadableStream& archive) :
- CRectShape(archive),
- FW_MProxy(ev, drawPart, drawPart->GetMainPresentation()),
- fDrawPart(drawPart),
- fFrozen(FALSE)
- {
- archive >> fFrameRect;
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::~CProxyShape
- //----------------------------------------------------------------------------------------
-
- CProxyShape::~CProxyShape()
- {
- FW_START_DESTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::FrameShapeRequested
- //----------------------------------------------------------------------------------------
-
- ODShape* CProxyShape::FrameShapeRequested(Environment* ev,
- FW_CEmbeddingFrame* embeddingFrame,
- ODFrame* odEmbeddedFrame,
- ODShape* requestedFrameShape)
- {
- // ----- get the bounding box of the asked frame shape
- FW_CRect frameRect = FW_GetShapeBoundingBox(ev, requestedFrameShape);
-
- fFrameRect.right = fFrameRect.left + frameRect.Width();
- fFrameRect.bottom = fFrameRect.top + frameRect.Height();
-
- // ----- Invalidate the old used Shape in case the embedded frame doesn't do it-----
- FW_CAcquiredODShape aqUsedShape = odEmbeddedFrame->AcquireUsedShape(ev, NULL);
- odEmbeddedFrame->Invalidate(ev, aqUsedShape, NULL);
-
- // ----- Don't forget to bump the refcount
- requestedFrameShape->Acquire(ev);
- return requestedFrameShape;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::UsedShapeChanged
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::UsedShapeChanged(Environment* ev, FW_CEmbeddingFrame* embeddingFrame, ODFrame* odEmbeddedFrame)
- {
- FW_CAcquiredODShape aqFrameShape = odEmbeddedFrame->AcquireFrameShape(ev, NULL);
- FW_CAcquiredODShape aqUsedShape = odEmbeddedFrame->AcquireUsedShape(ev, NULL);
-
- FW_CRect usedShapeRect = FW_GetShapeBoundingBox(ev, aqUsedShape);
- FW_CRect newShapeRect = FW_GetShapeBoundingBox(ev, aqFrameShape);
-
- newShapeRect.Intersection(usedShapeRect);
- newShapeRect.Offset(fFrameRect.left, fFrameRect.top);
-
- // ----- Get previous update shape -----
- FW_CAcquiredODShape aqInvalidShape = ::FW_NewODShape(ev);
- GetUpdateBox(ev, aqInvalidShape);
-
- // ----- Set the geometry of the shape -----
- SetRectGeometry(newShapeRect);
-
- // ----- Calculate the shape to update union minus intersection
- {
- FW_CAcquiredODShape aqNewUpdateBox = ::FW_NewODShape(ev);
- GetUpdateBox(ev, aqNewUpdateBox);
-
- FW_CAcquiredODShape aqIntersect(aqInvalidShape->Copy(ev));
- aqIntersect->Intersect(ev, aqNewUpdateBox);
-
- aqInvalidShape->Union(ev, aqNewUpdateBox);
-
- // ----- Clip our embedded facets using the union
- CDrawFacetClipper facetClipper(ev, fDrawPart);
- facetClipper.Clip(ev, embeddingFrame, aqInvalidShape);
-
- aqInvalidShape->Subtract(ev, aqIntersect);
- }
-
- fDrawPart->GetMainPresentation()->Invalidate(ev, aqInvalidShape);
-
- // ----- Invalidate the difference
- embeddingFrame->Invalidate(ev, aqInvalidShape);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::MoveBefore
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::MoveBefore(Environment* ev, CProxyShape* before)
- {
- FW_CAcquiredODPart aqEmbeddedPart = AcquireEmbeddedPart(ev);
- FW_CAcquiredODPart aqBeforePart = before->AcquireEmbeddedPart(ev);
-
- FW_CPresentationFacetIterator ite(ev, fDrawPart->GetMainPresentation());
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CFacetIterator ite1(ev, facet, kODChildrenOnly, kODFrontToBack);
- for (ODFacet* facet1 = ite1.First(ev); ite1.IsNotComplete(ev); facet1 = ite1.Next(ev))
- {
- FW_CAcquiredODPart aqODPart = facet1->GetFrame(ev)->AcquirePart(ev);
- if (aqODPart == aqEmbeddedPart)
- {
- FW_CFacetIterator ite2(ev, facet, kODChildrenOnly, kODFrontToBack);
- for (ODFacet* facet2 = ite2.First(ev); ite2.IsNotComplete(ev); facet2 = ite2.Next(ev))
- {
- FW_CAcquiredODPart aqODPart2 = facet2->GetFrame(ev)->AcquirePart(ev);
- if (aqODPart2 == aqBeforePart)
- {
- facet->MoveBefore(ev, facet1, facet2);
- break;
- }
- }
- }
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::MoveBehind
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::MoveBehind(Environment* ev, CProxyShape* behind)
- {
- FW_CAcquiredODPart aqEmbeddedPart = AcquireEmbeddedPart(ev);
- FW_CAcquiredODPart aqBehindPart = behind->AcquireEmbeddedPart(ev);
-
- FW_CPresentationFacetIterator ite(ev, fDrawPart->GetMainPresentation());
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CFacetIterator ite1(ev, facet, kODChildrenOnly, kODFrontToBack);
- for (ODFacet* facet1 = ite1.First(ev); ite1.IsNotComplete(ev); facet1 = ite1.Next(ev))
- {
- FW_CAcquiredODPart aqODPart = facet1->GetFrame(ev)->AcquirePart(ev);
- if (aqODPart == aqEmbeddedPart)
- {
- FW_CFacetIterator ite2(ev, facet1, kODChildrenOnly, kODFrontToBack);
- for (ODFacet* facet2 = ite2.First(ev); ite2.IsNotComplete(ev); facet2 = ite2.Next(ev))
- {
- FW_CAcquiredODPart aqODPart2 = facet2->GetFrame(ev)->AcquirePart(ev);
- if (aqODPart2 == aqBehindPart)
- {
- facet->MoveBehind(ev, facet1, facet2);
- break;
- }
- }
- }
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::RestoreShape
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::RestoreShape(Environment *ev, CDrawPart* drawPart)
- {
- CRectShape::RestoreShape(ev, drawPart);
-
- AttachEmbeddedFrames(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::Removed
- //----------------------------------------------------------------------------------------
- // the shape is going to be removed (for example for undo)
-
- void CProxyShape::Removed(Environment* ev)
- {
- CRectShape::Removed(ev);
-
- DetachEmbeddedFrames(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::Deleted
- //----------------------------------------------------------------------------------------
- // the shape is going to be deleted
-
- void CProxyShape::Deleted(Environment* ev)
- {
- CRectShape::Deleted(ev);
-
- RemoveEmbeddedFrames(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::Flatten
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::Flatten(FW_CWritableStream& archive)
- {
- CRectShape::Flatten(archive);
-
- archive << fFrameRect;
-
- // [HLX] I know it's bad but I know I am archiving to a storage unit
- CDrawWritableStream* drawArchive = (CDrawWritableStream*)&archive;
- Externalize(drawArchive->GetEnvironment(), drawArchive->GetStorageUnitView(), drawArchive->GetCloneInfo());
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::RenderShape
- //----------------------------------------------------------------------------------------
- // Because there can be multiple CProxyShape pointing on an embedded
- // frame, I only draw those belonging to this frame.
-
- void CProxyShape::RenderShape(Environment *ev, ODFacet* facet, FW_CGraphicContext& gc)
- {
- // if the canvas is not dynamic (printing) I let ODF/OpenDoc draw embedded facet
- if (!facet->GetCanvas(ev)->IsDynamic(ev))
- return;
-
- FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
- FW_CAcquiredODShape aqTempClipShape(gc.AcquireClip()); // GetClip returns a copy in content coordinate
-
- // ----- Because we are calling the draw method of an embedded facet, we want
- // ----- to save our context. The embedded facet will be using the same grafport
- // ----- and may not be restoring it.
- FW_CSaveRestoreContext src(gc);
-
- FW_CEmbeddedODFacetsIterator ite(ev, this, facet, kODFrontToBack);
- for (ODFacet *embeddedODFacet = ite.First(ev); ite.IsNotComplete(ev); embeddedODFacet = ite.Next(ev))
- {
- aqTempShape->CopyFrom(ev, aqTempClipShape);
-
- {
- FW_CAcquiredODTransform aqFrameTransform = embeddedODFacet->AcquireExternalTransform(ev, NULL);
- aqTempShape->InverseTransform(ev, aqFrameTransform); // parent content (me) -> embedded frame
- }
-
- #ifdef FW_BUILD_WIN
- // [HLX] bug in windows? the invalidShape is expected to be in pixels instead of points
- aqTempShape->Outset(ev, ff(1)); // [HLX] Because of rounding errors
- FW_CGraphicDevice *device = gc.GetGraphicDevice();
- device->PointToPixel(ev, aqTempShape);
- #endif
-
- embeddedODFacet->Draw(ev, aqTempShape, NULL);
- embeddedODFacet->DrawChildren(ev, aqTempShape, NULL);
-
- {
- FW_CAcquiredODShape aqClipShape = embeddedODFacet->AcquireClipShape(ev, NULL);
- aqTempShape->CopyFrom(ev, aqClipShape);
- }
-
- {
- FW_CAcquiredODTransform aqExternalTransform = embeddedODFacet->AcquireExternalTransform(ev, NULL);
- aqTempShape->Transform(ev, aqExternalTransform);
- }
-
- aqTempClipShape->Subtract(ev, aqTempShape);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::AdjustRectForPenSize
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::AdjustRectForPenSize(FW_CRect& rect, FW_Fixed penSize) const
- {
- // Does nothing because I have a pensize of zero
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::GetHandleCenter
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::GetHandleCenter(short whichHandle, FW_CPoint& center) const
- {
- CRectShape::GetHandleCenter(whichHandle, center);
- /*
- const FW_Fixed fxHalf = FW_ODFixedToFixed(0x00008000);
-
- switch (whichHandle)
- {
- case kInTopLeftCorner:
- center.x = fRect.left;
- center.y = fRect.top;
- break;
- case kInTopRightCorner:
- center.x = fRect.right - fxHalf;
- center.y = fRect.top;
- break;
- case kInBottomLeftCorner:
- center.x = fRect.left;
- center.y = fRect.bottom - fxHalf;
- break;
- case kInBottomRightCorner:
- center.x = fRect.right - fxHalf;
- center.y = fRect.bottom - fxHalf;
- break;
- }
- */
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::MapShape
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::MapShape(Environment *ev, CDrawPart* part, const FW_CRect& srcRect, const FW_CRect& dstRect)
- {
- CRectShape::MapShape(ev, part, srcRect, dstRect);
-
- fFrameRect = GetRectGeometry();
-
- // ----- Resize every embedded frames -----
- ChangeExternalTransforms(ev, fFrameRect.left, fFrameRect.top);
- ChangeFrameShapes(ev, fFrameRect.right - fFrameRect.left, fFrameRect.bottom - fFrameRect.top);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::OffsetShape
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::OffsetShape(Environment *ev, FW_Fixed xDelta, FW_Fixed yDelta)
- {
- CRectShape::OffsetShape(ev, xDelta, yDelta);
-
- fFrameRect.Offset(xDelta, yDelta);
-
- // ----- Change the external transform of all embedded facets -----
- ChangeExternalTransforms(ev, fFrameRect.left, fFrameRect.top);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::SelectShape
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::SelectShape(Environment *ev, FW_Boolean state)
- {
- CBaseShape::SelectShape(ev, state);
-
- // ----- Select all the embedded facet ----
- SetSelectState(ev, state);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::MovedAfter
- //----------------------------------------------------------------------------------------
- // shape has been moved after this
-
- void CProxyShape::MovedAfter(Environment *ev, CBaseShape* shape)
- {
- if (shape->GetShapeType() == kProxyShape)
- {
- ((CProxyShape*)shape)->MoveBehind(ev, this);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::MovedBefore
- //----------------------------------------------------------------------------------------
- // shape has been moved before this
-
- void CProxyShape::MovedBefore(Environment *ev, CBaseShape* shape)
- {
- if (shape->GetShapeType() == kProxyShape)
- {
- ((CProxyShape*)shape)->MoveBefore(ev, this);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::MovedFirst
- //----------------------------------------------------------------------------------------
- // this has been moved First
-
- void CProxyShape::MovedFirst(Environment *ev)
- {
- FW_CAcquiredODPart aqEmbeddedPart = AcquireEmbeddedPart(ev);
-
- FW_CPresentationFacetIterator ite(ev, fDrawPart->GetMainPresentation());
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CFacetIterator ite1(ev, facet, kODChildrenOnly, kODFrontToBack);
- for (ODFacet* facet1 = ite1.First(ev); ite1.IsNotComplete(ev); facet1 = ite1.Next(ev))
- {
- FW_CAcquiredODPart aqODPart = facet1->GetFrame(ev)->AcquirePart(ev);
- if (aqODPart == aqEmbeddedPart)
- facet->MoveBefore(ev, facet1, NULL);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::MovedLast
- //----------------------------------------------------------------------------------------
- // this has been moved Last
-
- void CProxyShape::MovedLast(Environment *ev)
- {
- FW_CAcquiredODPart aqEmbeddedPart = AcquireEmbeddedPart(ev);
-
- FW_CPresentationFacetIterator ite(ev, fDrawPart->GetMainPresentation());
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CFacetIterator ite1(ev, facet, kODChildrenOnly, kODFrontToBack);
- for (ODFacet* facet1 = ite1.First(ev); ite1.IsNotComplete(ev); facet1 = ite1.Next(ev))
- {
- FW_CAcquiredODPart aqODPart = facet1->GetFrame(ev)->AcquirePart(ev);
- if (aqODPart == aqEmbeddedPart)
- facet->MoveBehind(ev, facet1, NULL);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::SetFrozen
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CProxyShape::SetFrozen(FW_Boolean state)
- {
- if (fFrozen != state)
- {
- fFrozen = state;
- return TRUE;
- }
-
- return FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::IsFrozen
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CProxyShape::IsFrozen() const
- {
- return fFrozen;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::Read
- //----------------------------------------------------------------------------------------
-
- void* CProxyShape::Read(FW_CReadableStream& stream, FW_ClassTypeConstant type)
- {
- FW_UNUSED(type);
- // [HLX] This is a hack until I can register object with the archiver
- CDrawReadableStream *drawArchive = (CDrawReadableStream*)&stream;
- CProxyShape* proxyShape = FW_NEW(CProxyShape, (drawArchive->GetEnvironment(), drawArchive->GetDrawPart(), stream));
-
- proxyShape->Internalize(drawArchive->GetEnvironment(), drawArchive->GetStorageUnitView(), drawArchive->GetCloneInfo());
-
- return proxyShape;
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::SubtractToWindowClip
- //----------------------------------------------------------------------------------------
- // ATTENTION: windowClip is in Window coordinates. tempShape is just a working shape. It is
- // used by CBaseShape so I don't have to allocate a shape every time.
-
- void CProxyShape::SubtractToWindowClip(Environment *ev,
- CDrawFacetClipper* facetClipper,
- ODFacet* containingFacet,
- ODShape* windowClip, ODShape* tempShape)
- {
- FW_UNUSED(tempShape);
-
- FW_CEmbeddedODFacetsIterator ite(ev, this, containingFacet, kODFrontToBack);
- for (ODFacet *embeddedODFacet = ite.First(ev); ite.IsNotComplete(ev); embeddedODFacet = ite.Next(ev))
- {
- facetClipper->ClipOneEmbeddedFacet(ev, embeddedODFacet, windowClip);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::ChangeRenderVerb
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::ChangeRenderVerb(Environment *ev, CDrawPart* part, unsigned short renderVerb)
- {
- FW_UNUSED(ev);
- FW_UNUSED(part);
- FW_UNUSED(renderVerb);
-
- // We don't do anything
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::SetSubscribeLink
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::SetSubscribeLink(Environment* ev, CDrawSubscribeLink *subscribeLink)
- {
- CBaseShape::SetSubscribeLink(ev, subscribeLink);
- ChangeLinkStatus(ev, kODInLinkDestination);
- }
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::SetPublishLink
- //----------------------------------------------------------------------------------------
-
- void CProxyShape::SetPublishLink(Environment* ev, CDrawPublishLink *subscribeLink)
- {
- CBaseShape::SetPublishLink(ev, subscribeLink);
- ChangeLinkStatus(ev, kODInLinkSource);
- }
-
-
- //----------------------------------------------------------------------------------------
- // CProxyShape::IsInLinkDestination
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CProxyShape::IsInLinkDestination(Environment* ev)
- {
- // Check our local link status
- if (this->IsSubscribed())
- return TRUE;
-
- // Check the frame's link status
- FW_CProxyProxyFrameIterator iter(this);
- FW_CProxyFrame* frame = iter.First(); // only need to check one frame
- if (frame->GetFrame(ev)->GetLinkStatus(ev) == kODInLinkDestination)
- return TRUE;
-
- return FALSE;
- }
-