dcb36da295
Change-Id: I8a3245c6a4d687edbc95cf28b2932d80c86a7b65 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135828 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
200 lines
9.3 KiB
C++
200 lines
9.3 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR2D_BASEPROCESSOR2D_HXX
|
|
#define INCLUDED_DRAWINGLAYER_PROCESSOR2D_BASEPROCESSOR2D_HXX
|
|
|
|
#include <drawinglayer/drawinglayerdllapi.h>
|
|
|
|
#include <drawinglayer/primitive2d/Primitive2DVisitor.hxx>
|
|
#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
|
|
#include <drawinglayer/geometry/viewinformation2d.hxx>
|
|
|
|
|
|
namespace drawinglayer::processor2d
|
|
{
|
|
/** BaseProcessor2D class
|
|
|
|
Base class for all C++ implementations of instances which process
|
|
primitives.
|
|
|
|
Instances which process primitives can be renderers, but also stuff
|
|
for HitTests, BoundRect calculations and/or animation processing. The
|
|
main usage are renderers, but they are supposed to handle any primitive
|
|
processing.
|
|
|
|
The base implementation is constructed with a ViewInformation2D which
|
|
is accessible throughout the processor implementations. The idea is
|
|
to construct any processor with a given ViewInformation2D. To be able
|
|
to handle primitives which need to change the current transformation
|
|
(as e.g. TransformPrimitive2D) it is allowed for the processor implementation
|
|
to change its local value using updateViewInformation.
|
|
|
|
The basic processing method is process(..) which gets handed over the
|
|
sequence of primitives to process. For convenience of the C++ implementations,
|
|
the default implementation of process(..) maps all accesses to primitives to
|
|
single calls to processBasePrimitive2D(..) where the primitive in question is
|
|
already casted to the C++ implementation class.
|
|
|
|
The process(..) implementation makes a complete iteration over the given
|
|
sequence of primitives. If the Primitive is not derived from BasePrimitive2D
|
|
and thus not part of the C++ implementations, it converts ViewInformation2D
|
|
to the corresponding API implementation (a uno::Sequence< beans::PropertyValue >)
|
|
and recursively calls the method process(..) at the primitive with the decomposition
|
|
derived from that primitive. This is the preparation to handle unknown implementations
|
|
of the css::graphic::XPrimitive2D interface in the future.
|
|
|
|
So, to implement a basic processor, it is necessary to override and implement the
|
|
processBasePrimitive2D(..) method. A minimal renderer has to support the
|
|
Basic Primitives (see baseprimitive2d.hxx) and the Grouping Primitives (see
|
|
groupprimitive2d.hxx). These are (currently):
|
|
|
|
Basic Primitives:
|
|
|
|
- BitmapPrimitive2D (bitmap data, possibly with transparency)
|
|
- PointArrayPrimitive2D (single points)
|
|
- PolygonHairlinePrimitive2D (hairline curves/polygons)
|
|
- PolyPolygonColorPrimitive2D (colored polygons)
|
|
|
|
Grouping Primitives:
|
|
|
|
- TransparencePrimitive2D (objects with freely defined transparence)
|
|
- InvertPrimitive2D (for XOR)
|
|
- MaskPrimitive2D (for masking)
|
|
- ModifiedColorPrimitive2D (for a stack of color modifications)
|
|
- TransformPrimitive2D (for a transformation stack)
|
|
|
|
A processor doing so is a minimal processor. Of course a processor may
|
|
handle any higher-level primitive (that has a decomposition implementation)
|
|
for more direct data access or performance reasons, too.
|
|
|
|
The main part of a processBasePrimitive2D implementation is a switch..case
|
|
construct, looking like the following:
|
|
|
|
void foo::processBasePrimitive2D(const BasePrimitive2D& rCandidate)
|
|
{
|
|
switch(rCandidate.getPrimitive2DID())
|
|
{
|
|
case PRIMITIVE2D_ID_??? :
|
|
{
|
|
// process PRIMITIVE2D_ID_??? here...
|
|
|
|
...
|
|
|
|
break;
|
|
}
|
|
|
|
...
|
|
|
|
default :
|
|
{
|
|
// process recursively
|
|
process(rCandidate.get2DDecomposition(getViewInformation2D()));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
The default case makes the processor work with all complex primitives
|
|
by recursively using their decomposition.
|
|
|
|
You can also add a case for ignoring primitives by using:
|
|
|
|
case PRIMITIVE2D_ID_...IGNORE.A.. :
|
|
case PRIMITIVE2D_ID_...IGNORE.B.. :
|
|
case PRIMITIVE2D_ID_...IGNORE.C.. :
|
|
{
|
|
// ignore these primitives by neither processing nor
|
|
// recursively processing their decomposition
|
|
break;
|
|
}
|
|
|
|
Another useful case is embedding the processing of a complex primitive by
|
|
bracketing it with some actions:
|
|
|
|
case PRIMITIVE2D_ID_SOME_TEXT :
|
|
{
|
|
// encapsulate e.g. with changing local variables, e.g.
|
|
// sometimes it's good to know if a basic primitive is
|
|
// part of a text, especially when not handling the text
|
|
// self but by purpose want to handle the decomposed
|
|
// geometries in the processor
|
|
startText();
|
|
process(rCandidate.get2DDecomposition(getViewInformation2D()));
|
|
endText();
|
|
break;
|
|
}
|
|
|
|
As an example a processor collecting the outlines of a sequence of primitives
|
|
only needs to handle some Basic Primitives and create outline and collect
|
|
outline polygons e.g. for primitives with area like BitmapPrimitive2D (a
|
|
rectangle) and PolyPolygonColorPrimitive2D. When also handling the Grouping
|
|
Primitives MaskPrimitive2D (e.g. ignoring its content, using the mask polyPolygon)
|
|
and TransformPrimitive2D (to have the correct local transformation), a processor
|
|
creating the outline can be written using just four (4) primitives. As a tipp, it can
|
|
be helpful to add many for the purpose not interesting higher level primitives
|
|
to not force their decomposition to be created and/or parsed.
|
|
*/
|
|
class DRAWINGLAYER_DLLPUBLIC BaseProcessor2D : public drawinglayer::primitive2d::Primitive2DDecompositionVisitor
|
|
{
|
|
private:
|
|
/// The ViewInformation2D itself. It's private to isolate accesses to it
|
|
geometry::ViewInformation2D maViewInformation2D;
|
|
|
|
protected:
|
|
/* access method to allow the implementations to change the current
|
|
ViewInformation2D if needed. This allows isolating these accesses
|
|
later if needed
|
|
*/
|
|
void updateViewInformation(const geometry::ViewInformation2D& rViewInformation2D)
|
|
{
|
|
maViewInformation2D = rViewInformation2D;
|
|
}
|
|
|
|
/* as tooling, the process() implementation takes over API handling and calls this
|
|
virtual render method when the primitive implementation is BasePrimitive2D-based.
|
|
Default implementation does nothing
|
|
*/
|
|
virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate);
|
|
|
|
void process(const primitive2d::BasePrimitive2D& rCandidate);
|
|
|
|
// Primitive2DDecompositionVisitor
|
|
virtual void visit(const primitive2d::Primitive2DReference&) override final;
|
|
virtual void visit(const primitive2d::Primitive2DContainer&) override final;
|
|
virtual void visit(primitive2d::Primitive2DContainer&&) override final;
|
|
|
|
public:
|
|
/// constructor/destructor
|
|
explicit BaseProcessor2D(geometry::ViewInformation2D aViewInformation);
|
|
virtual ~BaseProcessor2D();
|
|
|
|
/// the central processing method
|
|
void process(const primitive2d::Primitive2DContainer& rSource);
|
|
|
|
/// data read access
|
|
const geometry::ViewInformation2D& getViewInformation2D() const { return maViewInformation2D; }
|
|
};
|
|
|
|
} // end of namespace drawinglayer::processor2d
|
|
|
|
|
|
#endif //INCLUDED_DRAWINGLAYER_PROCESSOR2D_BASEPROCESSOR2D_HXX
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|