Files
odfstudio/drawinglayer
Luboš Luňák 4deadc3c78 disentangle AA and B2D use in VCL drawing
A number of powerful functions using B2D polygons such as
OutputDevice::DrawPolyLineDirect() were used only if AA was enabled.
So e.g. dashing for an AA-ed polyline could be drawn directly
using the function, but with AA disabled had to be done manually
by a number of polygon operations. Which doesn't make much sense,
surely these powerful functions can also draw without AA if set so
(and indeed that's mostly the case). And DrawPolyLineDirect() even
had a flag to bypass the check.
So simply try to use B2D-based drawing whenever possible, AA or not.
The previous commit had already changed the naming of the AA option
to not include B2D in the name.

This seems to come from https://bz.apache.org/ooo/show_bug.cgi?id=88795,
which doesn't explain why AA only. There are other bugreports such as
https://bz.apache.org/ooo/show_bug.cgi?id=101491 and
https://bz.apache.org/ooo/show_bug.cgi?id=98289 that are related, but
there I cannot see any difference with this patch. And all unit tests
pass.

Change-Id: Ibb5938e8fff9b7452bac4bf12ed3e42fd3e5d645
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103354
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
2020-09-29 09:54:42 +02:00
..
2020-09-21 20:10:38 +02:00
…
…

Drawing API that can specify what to draw via a kind of display list.

Example of the DrawingLayer use is eg. in svx/source/xoutdev/xtabhtch.cxx:121.
A stripped down version with extended comments:

     // Create a hatch primitive (here a rectangle that will be filled with
     // the appropriate hatching, but has no border).
     // This will not draw it yet; it's so far only constructed to add it to a
     // display list later.
     const drawinglayer::primitive2d::Primitive2DReference aHatchPrimitive(
         new drawinglayer::primitive2d::PolyPolygonHatchPrimitive2D(...));

     // Create a rectangle around the hatch, to give it a border.
     const drawinglayer::primitive2d::Primitive2DReference aBlackRectanglePrimitive(
         new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(...));

     // Here we want to render to a virtual device (to later obtain the bitmap
     // out of that), so prepare it.
     VirtualDevice aVirtualDevice;

     // Create processor and draw primitives, to get it ready for rendering.
     std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
         drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(...));

     if (pProcessor2D)
     {
         // Fill-in the display list.
         drawinglayer::primitive2d::Primitive2DSequence aSequence(2);

         aSequence[0] = aHatchPrimitive;
         aSequence[1] = aBlackRectanglePrimitive;

         // Render it to the virtual device.
         pProcessor2D->process(aSequence);
         pProcessor2D.reset();
     }

     // Obtain the bitmap that was rendered from the virtual device, to re-use
     // it in the widget.
     aRetval = aVirtualDevice.GetBitmap(Point(0, 0), aVirtualDevice.GetOutputSizePixel());

== DrawingLayer glossary ==

Primitives - classes that represent what should be drawn.  It holds the data
what to draw, but does not contain any kind of the rendering.  Some of the
primitives are 'Basic primitives', that are primitives that cannot be
decomposed.  The rest of the primitives can be decomposed to the basic
primitives.

Decomposition - a way how to break down the more complicated primitives into
the basic primitives, and represent them via them; this logically makes the
plain Primitive2DSequence display list a hierarchy.
Eg. PolygonMarkerPrimitive2D can be decomposed to 2 hairlines
PolyPolygonHairlinePrimitive2D's, each with different color.

Processor - a class that goes through the hierarchy of the Primitives, and
renders it some way.  Various processors, like VclPixelProcessor2D (renders to
the screen), VclMetafileProcessor2D (renders to the VCL metafile, eg. for
printing), etc.

== How to Implement a new Primitive ("something new to draw") ==

* Create an ancestor of BasePrimitive2D
  (or of its ancestor if it fits the purpose better)

  * Assign it an ID [in drawinglayer_primitivetypes2d.hxx]

  * Implement its decomposition
    [virtual Primitive2DSequence create2DDecomposition(...)]

* Extend the (various) processor(s)
  If you need more than relying on just the decomposition

== Where is DrawingLayer used ==

* SdrObject(s) (rectangles, Circles, predefined shapes etc.)

* Selections

* Various smaller cases to 'just draw something'

  * Draw to a virtual device, and use the resulting bitmap (like the example
    above)

* Custom widgets (like the Header / Footer indicator button)