Calc Drawing Layer
==================

[ i.e. How to get objects and cells to interact nicely ]
[ "Abandon All Hope, All Ye Who Enter Here." ]

Overview:
--------
  - Calc allows objects (images, embedded documents, etc.) to be placed 
    anywhere -- within a single cell, overlapping many cells, etc.
  - Objects can be "anchored" to the Page or to a Cell
    - "Anchor to Cell" ~~ "whenever the cell moves, move the object so that
      it's still within the cell."
      - Buggy; see http://www.openoffice.org/issues/show_bug.cgi?id=47088
    - "Anchor to Page" ~~ "don't move the object, even if
      columns/rows/fonts/etc. are resized"
  - To support both Page and Cell anchoring, Objects are not kept within a
    Sc*Cell data structure.
  - Instead, we "magically" infer the row that the object belongs to by using
    it's position.

Implementation:
--------------
  - Drawing Layer implemented within ScDrawLayer <sc/inc/drwlayer.hxx>
  - ScDrawLayer logically contains a collection of 
    SdrPage <svx/svdpage.hxx> objects
    - via indirect base type method SdrModel::GetPage() <svx/svdmodel.hxx>
  - SdrPage contains a collection of SdrObject instances
    - Iterated over via SdrObjListIter
  - Key Point: SdrObjects know their location on the Drawing Layer via
    SdrObject::GetSnapRect() and/or SdrObject::GetLogicRect().
    - This location is in Millimeters!
  - Meanwhile, the rest of Calc stores everything in Twips -- e.g.
    ScDocument::FastGetRowHeight(), ScDocument::GetColWidth() return
    measurements in Twips, not in mm.
    - Necessitates converting Twips -> MM and MM -> Twips to determine 
      what row/column (i.e. cell) an Object is anchored to.
  - See ScDrawLayer::MoveAreaTwips() for an example.
  - Not all of Calc is in Twips; ScDrawLayer::MoveAreaTwips() needs to do
    MM->Twips to get object position, then do Twips->MM conversion to store
    Undo information.

Measuring:
---------
  - When drawing/moving/etc., the Mouse position (0,0) is the top-left corner
    of cell A1 (i.e. the row & column headers are ignored).
  - Measurements passed to ScHeaderControl::MouseButtonUp() are in Pixels
  - Pixels converted to Twips in ScRowBar::SetEntrySize() via
    nPixels/pViewData->GetPPTY(); GetPPTY() is based on
    ScGlobal::nScreenPPTY and the Zoom scale
  - For 100% scale on my laptop, ScGlobal::nScreenPPTY = 0.086.
  - So 430 pixels is 5000 Twips

Issues:
------
  - The Drawing Layer is littered with issues.
  - Conversion errors between hmm & twips causes positioning issues when
    moving objects.
    - Cut & Paste an object into a cell *should* insert it into the upper-left
      corner of the cell.
    - Frequently, the *actual* anchor is one cell to the left!
  - Row/Column resizing, both with mouse & via dialogs.
  - Redrawing -- changing tabs can alter the per-pixel position of objects 
    (as it causes a page refresh).
  - Row/Column Grouping is a WTF:
    - If an object is _completely_ within a group, and the group is
      collapsed+expanded, the object is now the size of the group.
    - If the object overlaps a group border, collapse+expand is "interesting."
  - Excel import: for certain files, embedded images which should be aligned
    along cell boundaries instead overlap cell borders.  Not sure what's
    happening here.
    - Need a better repro; can't manually reproduce this, but have a
      non-public file that demonstrates behvior.

Fixes?
------
  - Theory: many issues caused by lossy unit conversions from hmm->twips.  Fix
    is to replace arithmetic using HMM_PER_TWIPS with equivalent
    MetricField::ConvertDoubleValue() call.
  - This doesn't fix everything, in particular applying this fix to the Excel
    import filter doesn't fix the above Excel import issue.
  - Sun's new drawing layer (scheduled for OOo 2.4.0)?
  - Modify the Drawing Layer (SdrModel, etc.) to store coordinates in the same
    unit as Calc proper, thus eliminating lossy unit conversions.

Drawing Layer Internals:
-----------------------
  - Everything that draws on the screen goes through OutputDevice [vcl].
  - Drawing Layer objects have a slight detour through XOutputDevice, which
    then delegates calls to an OutputDevice.
  - OutputDevice knows about -- and performs -- unit conversions.
  - *Everything* that displays on the screen directly or indirectly inherits
    from OutputDevice.  This includes all buttons, menus, the Calc grid,
    status bars, scroll bars....
  - Many of them use different units. :-)
  - Calc requires a 1:1 mapping when going from "logical" to "device"
    coordinate systems.  For example, if you go from hmm -> pixels, the
    corresponding pixels -> hmm conversion needs to get the *same* value.
    - Required in ScDrawUtil::CalcScale().
  - OutputDevice uses X- and Y- scales to go from/to logical and device
    coordinate systems.
  - X- and Y- scales are computed by ScDrawUtil::CalcScale().
    - Takes screen DPI, View->Zoom, etc. into consideration.

