Miscellaneous Notes About Release 13

Here are some random thoughts and handy words about MacApp & ACS Release 13. They are not presented in any particular order.

Contents

  1. fprintf
  2. char* Coercion
  3. Returning CViewRect, CStr255_AC
  4. No More Square Dots
  5. No More Non-Styled Text
  6. No More Segments
  7. z-Ordered Clipping
  8. Control Removal
  9. View Coordinate System


fprintf

All fprintfs have been changed to ProgramReport_AC or ProgramBreak_AC.


char* Coercion

MacApp no longer uses the char* coercion operator. However we have left it in place so that developers are free to use it if they wish:

#if defined(qBackwardCompatible) && qBackwardCompatible
  // Returns a copy of the string on the stack. 
  // (as a null terminated c style string)
  // Note that this will not work when inlining 
  // is turned off. MacApp makes no use of this
  // operator internally. However, it is still 
  // provided as a convenience for compatibility.
  // Ideally you should write code that constructs 
  // a CChar255_AC in place from your string
  inline operator const char*() const
     { return CChar255_AC(*this); }
#endif


Returning CViewRect, CStr255_AC

Many functions now return a CViewRect, CViewPoint or CStr255_AC instead of passing the result through a parameter. This change avoids making assumptions about the passed-in value, optimizes parameter assignment and copying, reduces code size, and is much more convenient in usage. Many people do not realize that C/C++ compilers handle structure (class) function results by passing a hidden pointer to the resulting structure to the called function. Thus:

SetFrame(GetFrame(), kInvalidate);

is equivalent to

VRect theFrame;
GetFrame(theFrame);
SetFrame(theFrame, kInvalidate);

in terms of the actual code generated, with the exception that smart compilers can be even more aggressive in their optimization because the named object for the VRect is now anonymous. Named objects cannot be as aggressively optimized, that's why it is often better to construct objects only where needed such as:

SetFrame(VRect(10,10,100, 100), kInvalidate);

Also, C/V/Rect/Point and CStrxxx have efficient inline initializers that guarantee the objects are in usable shape which is generally a good thing, however, having functions like GetFrame() return the VRect means that the intermediate value can use a value constructor rather than a default constructor, followed by assignment or some other means of storing of value.

Thus, the first example above actually generates less and faster code while being more convenient in usage. Note that this is true for the functions that now return CStrxxx's as well.


No More Square Dots

Square dots was only used for old imagewriter code that made undocumented usage of the print record. When we cleaned MacApp up to only use approved, documented interfaces use of undocumented information had to be removed. By the way, there is no other printer that uses non-square dots, and the imagewriter is capable of square dots, thus a continuing source of code headaches and maintenance was removed.


No More Non-Styled Text

The isStyledText setting for TTEView has been removed, along with non-styled text support. Non-styled TextEdit is quite unfriendly to internationalization. MacApp makes extensive use of Script manager calls that are only friendly with styled TextEdit.


No More Segments

We no longer support segmentation for 68K builds in MacApp. In fact, all #pragma segment directives have been removed from the source code.

Maintaining segmentation is a nightmare. ACS has never had any segmentation pragmas and the ones in MacApp were seriously outdated. We did some sensitivity analysis on building 68K applications single segment and found that the overall memory requirements were not significantly different in most cases and actually lower in some cases. Further, we realized a performance benefit.

Developer feedback to the suggestion of going single-segment was predominantly positive.


z-Ordered Clipping

z-order clipping is now automatic. You may not even notice it because it is so fast.

R13 views have the following characteristics:

  • Arbitrary region shaping that is as FAST as old fashioned rectangular views but much much cooler because views can be shaped like your favorite cartoon character and will only draw, hililte, update, click test, etc. within the arbitrary region.
  • z-order clipping of overlapping sibling views. Yes, those "Tick" shaped views can overlap each other and will in fact clip each other in z-order.
  • But wait, there's more! There is also z-order clipping of subviews. Thus if you have a view that has an opaque subview (more on that in a minute) that subview will be clipped out of the focus for the parent view. This results in significantly less flicker when drawing things like a gray backdrop with big white scrollers since the area of the scrollers will be clipped when drawing the gray backdrop.

All this clipping is fast and automatic, but is also easily controllable via several avenues. First, there is a new member function for TViews called IsOpaque(). This method is used to indicate when a view is considered 'opaque', that is, it draws it's entire contents and no other bits are visible through it. Only opaque views are clipped. A view is considered opaque if its fIsOpaque flag is set or if it has an adorner that returns true for the adorner's IsOpaque. Erase adorners are considered opaque, they pass true for the default isOpaque parameter to the TAdorner constructor. TScrollers, TScrollBars are also considered opaque, they call SetOpacity(true) at construction.

IsOpaque is non-virtual. To be opaque, adorners or views must set their fIsOpaque flag via SetOpacity().


Control Removal

We now only remove controls from the WindowRecord's control list during activation and de-activation, the rest of the time we leave the controls alone. This allows system level utilities that expect to find controls on the WindowRecord's control list to still do so. Notably, this lets Speech Recognition and Apple Guide locate buttons and operate them. Also, we leave the control's location in window coordinates (where they are expected to be found by aforesaid utilities) except during actual MacApp drawing or operation of the control. During that time we move the control into MacApp space, do the operation, and then restore the control.


View Coordinate System

The following words were written recently and I thought you all might appreciate reading them:

fLocation is the location of a view expressed in its superview's coordinate system.

fTranslation is the offset to the zero point of the view's coordinate system. Views can have non-zero based coordinate systems by calling SetTranslation. Scrollers override this method in order to preserve screen bits when changing the origin.

fViewToQDOffset is the difference between the current view's origin in "View" space (which is 32bits in size) and its origin in QuickDraw space (which is only 16 bits in size). This lets us think and calculate in "View coordinates" but only convert them to QuickDraw coordinates at the last possible moment (via ViewToQD) when making QuickDraw calls. In fact, since most of the time you are not making QD calls, this means that MacApp stays in "View" coordinates most of the time.

fQDOrigin is the actual origin that will be set in QuickDraw when the view is focused. This origin is moved as necessary to accomodate scrolling and such but it is also calculated in (TView::UpdateCoordinates) in conjunction with fViewToQDOffset such that the fQDOrigin is always a multiple of 1024. The reason we do this is to overcome a problem with QD (that is in fact a shortcoming of most other frameworks and view system!!) When you move the QD origin in order to have a non-zero origin for a view (for scrolling and such) you can't just set the origin anywhere you (darn well) please. No, no, no, no, no! If you do that then the lines, shapes, regions and other stuff you draw with QD will work just fine... but, patterns will not render correctly since they are always drawn relative to QD's origin. Thus, we always move the QD origin in a power of two that is large enough to probably keep from interfering with large patterns. There is a discussion of the issue in comments in the UpdateCoordinates method.

 


Back to the Index



© Copyright 1997 by Apple Computer, Inc. -- Last Updated 7/31/97