office-gobmx/drawinglayer
Caolán McNamara d7056b1456 cid#1558088 COPY_INSTEAD_OF_MOVE
and

cid#1558080 COPY_INSTEAD_OF_MOVE
cid#1558077 COPY_INSTEAD_OF_MOVE
cid#1558055 COPY_INSTEAD_OF_MOVE
cid#1558043 COPY_INSTEAD_OF_MOVE
cid#1558039 COPY_INSTEAD_OF_MOVE
cid#1558015 COPY_INSTEAD_OF_MOVE
cid#1558014 COPY_INSTEAD_OF_MOVE
cid#1558009 COPY_INSTEAD_OF_MOVE
cid#1558002 COPY_INSTEAD_OF_MOVE
cid#1557998 COPY_INSTEAD_OF_MOVE
cid#1557996 COPY_INSTEAD_OF_MOVE
cid#1557990 COPY_INSTEAD_OF_MOVE
cid#1557986 COPY_INSTEAD_OF_MOVE
cid#1557980 COPY_INSTEAD_OF_MOVE
cid#1557971 COPY_INSTEAD_OF_MOVE
cid#1557968 COPY_INSTEAD_OF_MOVE
cid#1557967 COPY_INSTEAD_OF_MOVE
cid#1557961 COPY_INSTEAD_OF_MOVE
cid#1557959 COPY_INSTEAD_OF_MOVE
cid#1557958 COPY_INSTEAD_OF_MOVE
cid#1557956 COPY_INSTEAD_OF_MOVE
cid#1557953 COPY_INSTEAD_OF_MOVE
cid#1557949 COPY_INSTEAD_OF_MOVE
cid#1557947 COPY_INSTEAD_OF_MOVE
cid#1557940 COPY_INSTEAD_OF_MOVE
cid#1557931 COPY_INSTEAD_OF_MOVE
cid#1557930 COPY_INSTEAD_OF_MOVE
cid#1557915 COPY_INSTEAD_OF_MOVE
cid#1557913 COPY_INSTEAD_OF_MOVE
cid#1557910 COPY_INSTEAD_OF_MOVE
cid#1557886 COPY_INSTEAD_OF_MOVE
cid#1557884 COPY_INSTEAD_OF_MOVE
cid#1557880 COPY_INSTEAD_OF_MOVE
cid#1557875 COPY_INSTEAD_OF_MOVE
cid#1557871 COPY_INSTEAD_OF_MOVE
cid#1557862 COPY_INSTEAD_OF_MOVE
cid#1557847 COPY_INSTEAD_OF_MOVE
cid#1557845 COPY_INSTEAD_OF_MOVE
cid#1557844 COPY_INSTEAD_OF_MOVE
cid#1557843 COPY_INSTEAD_OF_MOVE
cid#1557838 COPY_INSTEAD_OF_MOVE
cid#1557835 COPY_INSTEAD_OF_MOVE
cid#1557834 COPY_INSTEAD_OF_MOVE
cid#1557828 COPY_INSTEAD_OF_MOVE
cid#1557823 COPY_INSTEAD_OF_MOVE
cid#1557817 COPY_INSTEAD_OF_MOVE
cid#1557813 COPY_INSTEAD_OF_MOVE
cid#1557812 COPY_INSTEAD_OF_MOVE

Change-Id: I55d4a920daa2d148683419169eb828325fd3c757
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171732
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
2024-08-11 20:14:54 +02:00
..
inc cid#1554812 COPY_INSTEAD_OF_MOVE 2024-07-29 14:50:38 +02:00
qa/unit loplugin:ostr in drawinglayer 2024-05-08 08:14:58 +02:00
source cid#1558088 COPY_INSTEAD_OF_MOVE 2024-08-11 20:14:54 +02:00
CppunitTest_drawinglayer_border.mk Use less libxml2 external headers dependency 2023-09-29 00:20:57 +02:00
CppunitTest_drawinglayer_processors.mk Prepare to run (select) tests during Emscripten build 2024-05-02 07:52:03 +02:00
drawinglayer.component
IwyuFilter_drawinglayer.yaml
Library_drawinglayer.mk CairoSDPR: Support ColorPolygon with AlphaGradient 2024-08-08 18:27:16 +02:00
Library_drawinglayercore.mk Use less libxml2 external headers dependency 2023-09-29 00:20:57 +02:00
Makefile
Module_drawinglayer.mk Separate core drawinglayer func. into drawinglayercore library 2021-12-22 12:10:10 +01:00
README.md Update README.md files 2022-04-16 20:43:11 +02:00

Drawing API

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(...));

 // 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)

Dumping DrawingLayer Primitives as XML

For debugging purposes, it is possible to dump the drawinglayer primitives as an xml file. The drawinglayer xml dump can show possible problems with the rendering.

For example, in emfio/qa/cppunit/emf/EmfImportTest.cxx, one can write:

Primitive2DSequence aSequence = parseEmf(u"emfio/qa/cppunit/wmf/data/stockobject.emf");
drawinglayer::Primitive2dXmlDump dumper;
Primitive2DContainer aContainer(aSequence);
dumper.dump(aContainer, "/tmp/drawyinglayer.xml");

Then, after invoking make CppunitTest_emfio_emf, /tmp/drawyinglayer.xml will be the dump of the drawinglayer primitives used to draw the emf file in LibreOffice. The top level tag will be .