diff --git a/core/annotations.h b/core/annotations.h index cd3370c19..43db9efc5 100644 --- a/core/annotations.h +++ b/core/annotations.h @@ -1,1751 +1,1764 @@ /*************************************************************************** * Copyright (C) 2005 by Enrico Ros * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef _OKULAR_ANNOTATIONS_H_ #define _OKULAR_ANNOTATIONS_H_ #include #include #include #include #include #include #include #include "okularcore_export.h" #include "area.h" namespace Okular { class Action; class Annotation; class AnnotationObjectRect; class AnnotationPrivate; class Document; class EmbeddedFile; class Page; class PagePrivate; class Sound; class Movie; class TextAnnotationPrivate; class LineAnnotationPrivate; class GeomAnnotationPrivate; class HighlightAnnotationPrivate; class StampAnnotationPrivate; class InkAnnotationPrivate; class CaretAnnotationPrivate; class FileAttachmentAnnotationPrivate; class SoundAnnotationPrivate; class MovieAnnotationPrivate; class ScreenAnnotationPrivate; class WidgetAnnotationPrivate; class RichMediaAnnotationPrivate; /** * @short Helper class for (recursive) annotation retrieval/storage. */ class OKULARCORE_EXPORT AnnotationUtils { public: /** * Restore an annotation (with revisions if needed) from the dom @p element. * * Returns a pointer to the complete annotation or 0 if element is invalid. */ static Annotation * createAnnotation( const QDomElement & element ); /** * Saves the @p annotation as a child of @p element taking * care of saving all revisions if it has any. */ static void storeAnnotation( const Annotation * annotation, QDomElement & element, QDomDocument & document ); /** * Returns the child element with the given @p name from the direct * children of @p parentNode or a null element if not found. */ static QDomElement findChildElement( const QDomNode & parentNode, const QString & name ); /** * Returns the geometry of the given @p annotation scaled by * @p scaleX and @p scaleY. */ static QRect annotationGeometry( const Annotation * annotation, double scaleX, double scaleY ); }; /** * @short Annotation struct holds properties shared by all annotations. * * An Annotation is an object (text note, highlight, sound, popup window, ..) * contained by a Page in the document. */ class OKULARCORE_EXPORT Annotation { /// @cond PRIVATE friend class AnnotationObjectRect; friend class Document; friend class DocumentPrivate; friend class ObjectRect; friend class Page; friend class PagePrivate; /// @endcond public: /** * Describes the type of annotation as defined in PDF standard. */ enum SubType { AText = 1, ///< A textual annotation ALine = 2, ///< A line annotation AGeom = 3, ///< A geometrical annotation AHighlight = 4, ///< A highlight annotation AStamp = 5, ///< A stamp annotation AInk = 6, ///< An ink annotation ACaret = 8, ///< A caret annotation AFileAttachment = 9, ///< A file attachment annotation ASound = 10, ///< A sound annotation AMovie = 11, ///< A movie annotation AScreen = 12, ///< A screen annotation AWidget = 13, ///< A widget annotation ARichMedia = 14,///< A rich media annotation A_BASE = 0 ///< The annotation base class }; /** * Describes additional properties of an annotation. */ enum Flag { Hidden = 1, ///< Is not shown in the document FixedSize = 2, ///< Has a fixed size FixedRotation = 4, ///< Has a fixed rotation DenyPrint = 8, ///< Cannot be printed DenyWrite = 16, ///< Cannot be changed DenyDelete = 32, ///< Cannot be deleted ToggleHidingOnMouse = 64, ///< Can be hidden/shown by mouse click External = 128, ///< Is stored external ExternallyDrawn = 256, ///< Is drawn externally (by the generator which provided it) @since 0.10 (KDE 4.4) BeingMoved = 512, ///< Is being moved (mouse drag and drop). If ExternallyDrawn, the generator must not draw it @since 0.15 (KDE 4.9) BeingResized = 1024 ///< Is being resized (mouse drag and drop). If ExternallyDrawn, the generator must not draw it @since 1.1.0 }; /** * Describes possible line styles for @see ALine annotation. */ enum LineStyle { Solid = 1, ///< A solid line Dashed = 2, ///< A dashed line Beveled = 4, ///< A beveled line Inset = 8, ///< An inset line Underline = 16 ///< An underline }; /** * Describes possible line effects for @see ALine annotation. */ enum LineEffect { NoEffect = 1, ///< No effect Cloudy = 2 ///< The cloudy effect }; /** * Describes the scope of revision information. */ enum RevisionScope { Reply = 1, ///< Belongs to a reply Group = 2, ///< Belongs to a group Delete = 4 ///< Belongs to a deleted paragraph }; /** * Describes the type of revision information. */ enum RevisionType { None = 1, ///< Not specified Marked = 2, ///< Is marked Unmarked = 4, ///< Is unmarked Accepted = 8, ///< Has been accepted Rejected = 16, ///< Was rejected Cancelled = 32, ///< Has been cancelled Completed = 64 ///< Has been completed }; /** * Describes the type of additional actions. * * @since 0.16 (KDE 4.10) */ enum AdditionalActionType { PageOpening, ///< Performed when the page containing the annotation is opened. PageClosing, ///< Performed when the page containing the annotation is closed. CursorEntering, ///< Performed when the cursor enters the annotation's active area @since 1.5 CursorLeaving, ///< Performed when the cursor exists the annotation's active area @since 1.5 MousePressed, ///< Performed when the mouse button is pressed inside the annotation's active area @since 1.5 MouseReleased, ///< Performed when the mouse button is released inside the annotation's active area @since 1.5 FocusIn, ///< Performed when the annotation receives the input focus @since 1.5 FocusOut, ///< Performed when the annotation loses the input focus @since 1.5 }; /** * A function to be called when the annotation is destroyed. * * @warning the function must *not* call any virtual function, * nor subcast. * * @since 0.7 (KDE 4.1) */ typedef void ( * DisposeDataFunction )( const Okular::Annotation * ); /** * Destroys the annotation. */ virtual ~Annotation(); /** * Sets the @p author of the annotation. */ void setAuthor( const QString &author ); /** * Returns the author of the annotation. */ QString author() const; /** * Sets the @p contents of the annotation. */ void setContents( const QString &contents ); /** * Returns the contents of the annotation. */ QString contents() const; /** * Sets the unique @p name of the annotation. */ void setUniqueName( const QString &name ); /** * Returns the unique name of the annotation. */ QString uniqueName() const; /** * Sets the last modification @p date of the annotation. * * The date must be before or equal to QDateTime::currentDateTime() */ void setModificationDate( const QDateTime &date ); /** * Returns the last modification date of the annotation. */ QDateTime modificationDate() const; /** * Sets the creation @p date of the annotation. * * The date must be before or equal to @see modificationDate() */ void setCreationDate( const QDateTime &date ); /** * Returns the creation date of the annotation. */ QDateTime creationDate() const; /** * Sets the @p flags of the annotation. * @see @ref Flag */ void setFlags( int flags ); /** * Returns the flags of the annotation. * @see @ref Flag */ int flags() const; /** * Sets the bounding @p rectangle of the annotation. */ void setBoundingRectangle( const NormalizedRect &rectangle ); /** * Returns the bounding rectangle of the annotation. */ NormalizedRect boundingRectangle() const; /** * Returns the transformed bounding rectangle of the annotation. * * This rectangle must be used when showing annotations on screen * to have them rotated correctly. */ NormalizedRect transformedBoundingRectangle() const; /** * Move the annotation by the specified coordinates. * * @see canBeMoved() */ void translate( const NormalizedPoint &coord ); /** * Adjust the annotation by the specified coordinates. * Adds coordinates of @p deltaCoord1 to annotations top left corner, * and @p deltaCoord2 to the bottom right. * * @see canBeResized() */ void adjust( const NormalizedPoint & deltaCoord1, const NormalizedPoint & deltaCoord2 ); /** * The Style class contains all information about style of the * annotation. */ class OKULARCORE_EXPORT Style { public: /** * Creates a new style. */ Style(); /** * Destroys the style. */ ~Style(); Style( const Style &other ); Style& operator=( const Style &other ); /** * Sets the @p color of the style. */ void setColor( const QColor &color ); /** * Returns the color of the style. */ QColor color() const; /** * Sets the @p opacity of the style. */ void setOpacity( double opacity ); /** * Returns the opacity of the style. */ double opacity() const; /** * Sets the @p width of the style. */ void setWidth( double width ); /** * Returns the width of the style. */ double width() const; /** * Sets the line @p style of the style. */ void setLineStyle( LineStyle style ); /** * Returns the line style of the style. */ LineStyle lineStyle() const; /** * Sets the x-corners of the style. */ void setXCorners( double xCorners ); /** * Returns the x-corners of the style. */ double xCorners() const; /** * Sets the y-corners of the style. */ void setYCorners( double yCorners ); /** * Returns the y-corners of the style. */ double yCorners() const; /** * Sets the @p marks of the style. */ void setMarks( int marks ); /** * Returns the marks of the style. */ int marks() const; /** * Sets the @p spaces of the style. */ void setSpaces( int spaces ); /** * Returns the spaces of the style. */ int spaces() const; /** * Sets the line @p effect of the style. */ void setLineEffect( LineEffect effect ); /** * Returns the line effect of the style. */ LineEffect lineEffect() const; /** * Sets the effect @p intensity of the style. */ void setEffectIntensity( double intensity ); /** * Returns the effect intensity of the style. */ double effectIntensity() const; private: class Private; Private* const d; }; /** * Returns a reference to the style object of the annotation. */ Style & style(); /** * Returns a const reference to the style object of the annotation. */ const Style & style() const; /** * The Window class contains all information about the popup window * of the annotation that is used to edit the content and properties. */ class OKULARCORE_EXPORT Window { public: /** * Creates a new window. */ Window(); /** * Destroys the window. */ ~Window(); Window( const Window &other ); Window& operator=( const Window &other ); /** * Sets the @p flags of the window. */ void setFlags( int flags ); /** * Returns the flags of the window. */ int flags() const; /** * Sets the top-left @p point of the window. */ void setTopLeft( const NormalizedPoint &point ); /** * Returns the top-left point of the window. */ NormalizedPoint topLeft() const; /** * Sets the @p width of the window. */ void setWidth( int width ); /** * Returns the width of the window. */ int width() const; /** * Sets the @p height of the window. */ void setHeight( int height ); /** * Returns the height of the window. */ int height() const; /** * Sets the @p title of the window. */ void setTitle( const QString &title ); /** * Returns the title of the window. */ QString title() const; /** * Sets the @p summary of the window. */ void setSummary( const QString &summary ); /** * Returns the summary of the window. */ QString summary() const; private: class Private; Private* const d; }; /** * Returns a reference to the window object of the annotation. */ Window & window(); /** * Returns a const reference to the window object of the annotation. */ const Window & window() const; /** * The Revision class contains all information about the revision * of the annotation. */ class Revision { public: /** * Creates a new revision. */ Revision(); /** * Destroys the revision. */ ~Revision(); Revision( const Revision &other ); Revision& operator=( const Revision &other ); /** * Sets the @p annotation the revision belongs to. */ void setAnnotation( Annotation *annotation ); /** * Returns the annotation the revision belongs to. */ Annotation *annotation() const; /** * Sets the @p scope of the revision. * @see RevisionScope */ void setScope( RevisionScope scope ); /** * Returns the scope of the revision. */ RevisionScope scope() const; /** * Sets the @p type of the revision. * @see RevisionType */ void setType( RevisionType type ); /** * Returns the type of the revision. */ RevisionType type() const; private: class Private; Private* const d; }; /** * Returns a reference to the revision list of the annotation. */ QLinkedList< Revision > & revisions(); /** * Returns a reference to the revision list of the annotation. */ const QLinkedList< Revision > & revisions() const; /** * Sets the "native" @p id of the annotation. * * This is for use of the Generator, that can optionally store an * handle (a pointer, an identifier, etc) of the "native" annotation * object, if any. * * @note Okular makes no use of this * * @since 0.7 (KDE 4.1) */ void setNativeId( const QVariant &id ); /** * Returns the "native" id of the annotation. * * @since 0.7 (KDE 4.1) */ QVariant nativeId() const; /** * Sets a function to be called when the annotation is destroyed. * * @warning the function must *not* call any virtual function, * nor subcast. * * @since 0.7 (KDE 4.1) */ void setDisposeDataFunction( DisposeDataFunction func ); /** * Returns whether the annotation can be moved. * * @since 0.7 (KDE 4.1) */ bool canBeMoved() const; /** * Returns whether the annotation can be resized. */ bool canBeResized() const; /** * Returns whether the annotation dialog should be open after creation of the annotation or not * * @since 0.13 (KDE 4.7) */ bool openDialogAfterCreation() const; /** * Returns the sub type of the annotation. */ virtual SubType subType() const = 0; /** * Stores the annotation as xml in @p document under the given parent @p node. */ virtual void store( QDomNode & node, QDomDocument & document ) const; /** * Retrieve the QDomNode representing this annotation's properties * @since 0.17 (KDE 4.11) */ QDomNode getAnnotationPropertiesDomNode() const; /** * Sets annotations internal properties according to the contents of @p node * * @since 0.17 (KDE 4.11) */ void setAnnotationProperties( const QDomNode & node ); protected: /// @cond PRIVATE Annotation( AnnotationPrivate &dd ); Annotation( AnnotationPrivate &dd, const QDomNode &description ); Q_DECLARE_PRIVATE( Annotation ) AnnotationPrivate *d_ptr; /// @endcond private: Q_DISABLE_COPY( Annotation ) }; /** * @short Native annotation interface * * Generators can subclass it to provide native annotation support. * Generators can use Annotation::setNativeId to store per-annotation data. * * @since 0.15 (KDE 4.9) */ class OKULARCORE_EXPORT AnnotationProxy { public: enum Capability { Addition, ///< Generator can create native annotations Modification, ///< Generator can edit native annotations Removal ///< Generator can remove native annotations }; /** * Destroys the annotation proxy. */ virtual ~AnnotationProxy(); /** * Query for the supported capabilities. */ virtual bool supports( Capability capability ) const = 0; /** * Called when a new @p annotation is added to a @p page. * * @note Only called if supports(Addition) == true */ virtual void notifyAddition( Annotation *annotation, int page ) = 0; /** * Called after an existing @p annotation at a given @p page is modified. * * Generator can call @p annotation getters to get the new values. * @p appearanceChanged tells if a non-visible property was modified * * @note Only called if supports(Modification) == true */ virtual void notifyModification( const Annotation *annotation, int page, bool appearanceChanged ) = 0; /** * Called when an existing @p annotation at a given @p page is removed. * * @note Only called if supports(Removal) == true */ virtual void notifyRemoval( Annotation *annotation, int page ) = 0; }; class OKULARCORE_EXPORT TextAnnotation : public Annotation { public: /** * Describes the type of the text. */ enum TextType { Linked, ///< The annotation is linked to a text InPlace ///< The annotation is located next to the text }; /** * Describes the style of the text. */ enum InplaceIntent { Unknown, ///< Unknown style Callout, ///< Callout style TypeWriter ///< Type writer style }; /** * Creates a new text annotation. */ TextAnnotation(); /** * Creates a new text annotation from the xml @p description */ explicit TextAnnotation( const QDomNode &description ); /** * Destroys the text annotation. */ ~TextAnnotation(); /** * Sets the text @p type of the text annotation. * @see TextType */ void setTextType( TextType type ); /** * Returns the text type of the text annotation. */ TextType textType() const; /** * Sets the @p icon of the text annotation. */ void setTextIcon( const QString &icon ); /** * Returns the icon of the text annotation. */ QString textIcon() const; /** * Sets the @p font of the text annotation. */ void setTextFont( const QFont &font ); /** * Returns the font of the text annotation. */ QFont textFont() const; /** * Sets the @p color of inplace text. * * @since 1.6 */ void setTextColor( const QColor &color ); /** * Returns the color of inplace text. * * @since 1.6 */ QColor textColor() const; /** * Sets the inplace @p alignment of the text annotation. */ void setInplaceAlignment( int alignment ); /** * Returns the inplace alignment of the text annotation. */ int inplaceAlignment() const; /** * Sets the inplace callout @p point at @p index. * * @p index must be between 0 and 2. */ void setInplaceCallout( const NormalizedPoint &point, int index ); /** * Returns the inplace callout point for @p index. * * @p index must be between 0 and 2. */ NormalizedPoint inplaceCallout( int index ) const; /** * Returns the transformed (e.g. rotated) inplace callout point for @p index. * * @p index must be between 0 and 2. */ NormalizedPoint transformedInplaceCallout( int index ) const; /** * Returns the inplace @p intent of the text annotation. * @see InplaceIntent */ void setInplaceIntent( InplaceIntent intent ); /** * Returns the inplace intent of the text annotation. */ InplaceIntent inplaceIntent() const; /** * Returns the sub type of the text annotation. */ SubType subType() const override; /** * Stores the text annotation as xml in @p document under the given parent @p node. */ void store( QDomNode &node, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( TextAnnotation ) Q_DISABLE_COPY( TextAnnotation ) }; class OKULARCORE_EXPORT LineAnnotation : public Annotation { public: /** * Describes the line ending style. */ enum TermStyle { Square, ///< Using a square Circle, ///< Using a circle Diamond, ///< Using a diamond OpenArrow, ///< Using an open arrow ClosedArrow, ///< Using a closed arrow None, ///< No special ending style Butt, ///< Using a butt ending ROpenArrow, ///< Using an arrow opened at the right side RClosedArrow, ///< Using an arrow closed at the right side Slash ///< Using a slash }; /** * Describes the line intent. */ enum LineIntent { Unknown, ///< Unknown intent Arrow, ///< Arrow intent Dimension, ///< Dimension intent PolygonCloud ///< Polygon cloud intent }; /** * Creates a new line annotation. */ LineAnnotation(); /** * Creates a new line annotation from the xml @p description */ explicit LineAnnotation( const QDomNode &description ); /** * Destroys the line annotation. */ ~LineAnnotation(); /** * Sets the normalized line @p points of the line annotation. */ void setLinePoints( const QLinkedList &points ); /** * Returns the normalized line points of the line annotation. */ QLinkedList linePoints() const; /** * Returns the transformed (e.g. rotated) normalized line points * of the line annotation. */ QLinkedList transformedLinePoints() const; /** * Sets the line starting @p style of the line annotation. * @see TermStyle */ void setLineStartStyle( TermStyle style ); /** * Returns the line starting style of the line annotation. */ TermStyle lineStartStyle() const; /** * Sets the line ending @p style of the line annotation. * @see TermStyle */ void setLineEndStyle( TermStyle style ); /** * Returns the line ending style of the line annotation. */ TermStyle lineEndStyle() const; /** * Sets whether the line shall be @p closed. */ void setLineClosed( bool closed ); /** * Returns whether the line shall be closed. */ bool lineClosed() const; /** * Sets the inner line @p color of the line annotation. */ void setLineInnerColor( const QColor &color ); /** * Returns the inner line color of the line annotation. */ QColor lineInnerColor() const; /** * Sets the leading forward @p point of the line annotation. */ void setLineLeadingForwardPoint( double point ); /** * Returns the leading forward point of the line annotation. */ double lineLeadingForwardPoint() const; /** * Sets the leading backward @p point of the line annotation. */ void setLineLeadingBackwardPoint( double point ); /** * Returns the leading backward point of the line annotation. */ double lineLeadingBackwardPoint() const; /** * Sets whether the caption shall be @p shown. */ void setShowCaption( bool shown ); /** * Returns whether the caption shall be shown. */ bool showCaption() const; /** * Sets the line @p intent of the line annotation. * @see LineIntent */ void setLineIntent( LineIntent intent ); /** * Returns the line intent of the line annotation. */ LineIntent lineIntent() const; /** * Returns the sub type of the line annotation. */ SubType subType() const override; /** * Stores the line annotation as xml in @p document under the given parent @p node. */ void store( QDomNode &node, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( LineAnnotation ) Q_DISABLE_COPY( LineAnnotation ) }; class OKULARCORE_EXPORT GeomAnnotation : public Annotation { public: // common enums enum GeomType { InscribedSquare, ///< Draw a square InscribedCircle ///< Draw a circle }; /** * Creates a new geometrical annotation. */ GeomAnnotation(); /** * Creates a new geometrical annotation from the xml @p description */ explicit GeomAnnotation( const QDomNode &description ); /** * Destroys the geometrical annotation. */ ~GeomAnnotation(); /** * Sets the geometrical @p type of the geometrical annotation. * @see GeomType */ void setGeometricalType( GeomType type ); /** * Returns the geometrical type of the geometrical annotation. */ GeomType geometricalType() const; /** * Sets the inner @p color of the geometrical annotation. */ void setGeometricalInnerColor( const QColor &color ); /** * Returns the inner color of the geometrical annotation. */ QColor geometricalInnerColor() const; /** * Returns the sub type of the geometrical annotation. */ SubType subType() const override; /** * Stores the geometrical annotation as xml in @p document * under the given parent @p node. */ void store( QDomNode &node, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( GeomAnnotation ) Q_DISABLE_COPY( GeomAnnotation ) }; class OKULARCORE_EXPORT HighlightAnnotation : public Annotation { public: /** * Describes the highlighting style of the annotation. */ enum HighlightType { Highlight, ///< Highlights the text Squiggly, ///< Squiggles the text Underline, ///< Underlines the text StrikeOut ///< Strikes out the text }; /** * Creates a new highlight annotation. */ HighlightAnnotation(); /** * Creates a new highlight annotation from the xml @p description */ explicit HighlightAnnotation( const QDomNode &description ); /** * Destroys the highlight annotation. */ ~HighlightAnnotation(); /** * Sets the @p type of the highlight annotation. * @see HighlightType */ void setHighlightType( HighlightType type ); /** * Returns the type of the highlight annotation. */ HighlightType highlightType() const; /** - * The Quad class contains 8 coordinates and style definitions - * which describe a line part of the whole highlight annotation. + * @short Describes a highlight quad of a text markup annotation. + * + * The Quad is a closed path of 4 NormalizedPoints. + * Another set of 4 NormalizedPoints can be generated with transform(), + * e. g. to get highlighting coordinates on a rotated PageViewItem. + * Additionally, Quad stores some geometry related style attributes. + * + * To enable correct rendering of the annotation, + * the points 0 and 1 must describe the bottom edge of the quad + * (relative to the text orientation). + * + * @see NormalizedPoint */ class OKULARCORE_EXPORT Quad { public: /** * Creates a new quad. */ Quad(); /** * Destroys the quad. */ ~Quad(); Quad( const Quad &other ); Quad& operator=( const Quad &other ); /** * Sets the normalized @p point at @p index. * * @p index must be between 0 and 3. */ void setPoint( const NormalizedPoint &point, int index ); /** * Returns the normalized point at @p index. * * @p index must be between 0 and 3. */ NormalizedPoint point( int index ) const; /** * Returns the transformed (e.g. rotated) normalized point at @p index. * * @p index must be between 0 and 3. */ NormalizedPoint transformedPoint( int index ) const; /** * Sets whether a cap should be used at the start. */ void setCapStart( bool value ); /** * Returns whether a cap should be used at the start. */ bool capStart() const; /** * Sets whether a cap should be used at the end. */ void setCapEnd( bool value ); /** * Returns whether a cap should be used at the end. */ bool capEnd() const; /** * Sets the @p width of the drawing feather. */ void setFeather( double width ); /** * Returns the width of the drawing feather. */ double feather() const; /** * Transforms the quad coordinates with the transformation defined * by @p matrix. + * + * The transformed coordinates will be accessible with transformedPoint(). + * The coordinates returned by point() are not affected. */ void transform( const QTransform &matrix ); private: class Private; Private* const d; }; /** * Returns a reference to the quad list of the highlight annotation. */ QList< Quad > & highlightQuads(); /** * Returns the sub type of the highlight annotation. */ SubType subType() const override; /** * Stores the highlight annotation as xml in @p document * under the given parent @p node. */ void store( QDomNode &node, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( HighlightAnnotation ) Q_DISABLE_COPY( HighlightAnnotation ) }; class OKULARCORE_EXPORT StampAnnotation : public Annotation { public: /** * Creates a new stamp annotation. */ StampAnnotation(); /** * Creates a new stamp annotation from the xml @p description */ explicit StampAnnotation( const QDomNode &description ); /** * Destroys the stamp annotation. */ ~StampAnnotation(); /** * Sets the @p name of the icon for the stamp annotation. */ void setStampIconName( const QString &name ); /** * Returns the name of the icon. */ QString stampIconName() const; /** * Returns the sub type of the stamp annotation. */ SubType subType() const override; /** * Stores the stamp annotation as xml in @p document * under the given parent @p node. */ void store( QDomNode &node, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( StampAnnotation ) Q_DISABLE_COPY( StampAnnotation ) }; class OKULARCORE_EXPORT InkAnnotation : public Annotation { public: /** * Creates a new ink annotation. */ InkAnnotation(); /** * Creates a new ink annotation from the xml @p description */ explicit InkAnnotation( const QDomNode &description ); /** * Destroys the ink annotation. */ ~InkAnnotation(); /** * Sets the @p paths of points for the ink annotation. */ void setInkPaths( const QList< QLinkedList > &paths ); /** * Returns the paths of points of the ink annotation. */ QList< QLinkedList > inkPaths() const; /** * Returns the paths of transformed (e.g. rotated) points of * the ink annotation. */ QList< QLinkedList > transformedInkPaths() const; /** * Returns the sub type of the ink annotation. */ SubType subType() const override; /** * Stores the ink annotation as xml in @p document * under the given parent @p node. */ void store( QDomNode &node, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( InkAnnotation ) Q_DISABLE_COPY( InkAnnotation ) }; class OKULARCORE_EXPORT CaretAnnotation : public Annotation { public: /** * Describes the highlighting style of the annotation. */ enum CaretSymbol { None, ///< No symbol to be associated with the text P ///< A 'paragraph' symbol }; /** * Creates a new caret annotation. */ CaretAnnotation(); /** * Creates a new caret annotation from the xml @p description */ explicit CaretAnnotation( const QDomNode &description ); /** * Destroys the caret annotation. */ ~CaretAnnotation(); /** * Sets the @p symbol for the caret annotation. */ void setCaretSymbol( CaretAnnotation::CaretSymbol symbol ); /** * Returns the symbol of the annotation. */ CaretAnnotation::CaretSymbol caretSymbol() const; /** * Returns the sub type of the caret annotation. */ SubType subType() const override; /** * Stores the caret annotation as xml in @p document * under the given parent @p node. */ void store( QDomNode &node, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( CaretAnnotation ) Q_DISABLE_COPY( CaretAnnotation ) }; class OKULARCORE_EXPORT FileAttachmentAnnotation : public Annotation { public: /** * Creates a new file attachment annotation. */ FileAttachmentAnnotation(); /** * Creates a new file attachment annotation from the xml @p description */ explicit FileAttachmentAnnotation( const QDomNode &description ); /** * Destroys the file attachment annotation. */ virtual ~FileAttachmentAnnotation(); /** * Gets the name of the icon. */ QString fileIconName() const; /** * Sets the @p name of the icon for the file attachment annotation. */ void setFileIconName( const QString &name ); /** * Gets the embedded file object. */ EmbeddedFile* embeddedFile() const; /** * Sets the @p object representing the embedded file of the file * attachment annotation. */ void setEmbeddedFile( EmbeddedFile *object ); /** * Returns the sub type of the file attachment annotation. */ SubType subType() const override; /** * Stores the file attachment annotation as xml in @p document * under the given parent @p node. */ void store( QDomNode &node, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( FileAttachmentAnnotation ) Q_DISABLE_COPY( FileAttachmentAnnotation ) }; /** * \short Sound annotation. * * The sound annotation represents a sound to be played when activated. * * @since 0.7 (KDE 4.1) */ class OKULARCORE_EXPORT SoundAnnotation : public Annotation { public: /** * Creates a new sound annotation. */ SoundAnnotation(); /** * Creates a new sound annotation from the xml @p description */ explicit SoundAnnotation( const QDomNode &description ); /** * Destroys the sound annotation. */ virtual ~SoundAnnotation(); /** * Gets the name of the icon. */ QString soundIconName() const; /** * Sets the @p name of the icon for the sound annotation. */ void setSoundIconName( const QString &name ); /** * Gets the sound object. */ Sound* sound() const; /** * Sets the @p object representing the sound of the file * attachment annotation. */ void setSound( Sound *object ); /** * Returns the sub type of the sound annotation. */ SubType subType() const override; /** * Stores the sound annotation as xml in @p document * under the given parent @p node. */ void store( QDomNode &node, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( SoundAnnotation ) Q_DISABLE_COPY( SoundAnnotation ) }; /** * \short Movie annotation. * * The movie annotation represents a movie to be played when activated. * * @since 0.8 (KDE 4.2) */ class OKULARCORE_EXPORT MovieAnnotation : public Annotation { public: /** * Creates a new movie annotation. */ MovieAnnotation(); /** * Creates a new movie annotation from the xml @p description */ explicit MovieAnnotation( const QDomNode &description ); /** * Destroys the movie annotation. */ virtual ~MovieAnnotation(); /** * Gets the movie object. */ Movie* movie() const; /** * Sets the new @p movie object. */ void setMovie( Movie *movie ); /** * Returns the sub type of the movie annotation. */ SubType subType() const override; /** * Stores the movie annotation as xml in @p document * under the given @p parentNode. */ void store( QDomNode &parentNode, QDomDocument &document ) const override; private: Q_DECLARE_PRIVATE( MovieAnnotation ) Q_DISABLE_COPY( MovieAnnotation ) }; /** * \short Screen annotation. * * The screen annotation specifies a region of a page upon which media clips * may be played. It also serves as an object from which actions can be triggered. * * @since 0.16 (KDE 4.10) */ class OKULARCORE_EXPORT ScreenAnnotation : public Annotation { public: /** * Creates a new screen annotation. */ ScreenAnnotation(); /** * Creates a new screen annotation from the xml @p description */ explicit ScreenAnnotation( const QDomNode &description ); /** * Destroys the screen annotation. */ virtual ~ScreenAnnotation(); /** * Returns the sub type of the screen annotation. */ SubType subType() const override; /** * Stores the screen annotation as xml in @p document * under the given @p parentNode. */ void store( QDomNode &parentNode, QDomDocument &document ) const override; /** * Sets the @p action that is executed when the annotation is triggered. * * @since 0.16 (KDE 4.10) */ void setAction( Action *action ); /** * Returns the action that is executed when the annotation is triggered or @c 0 if not action has been defined. * * @since 0.16 (KDE 4.10) */ Action* action() const; /** * Sets the additional @p action of the given @p type. * * @since 0.16 (KDE 4.10) */ void setAdditionalAction( AdditionalActionType type, Action *action ); /** * Returns the additional action of the given @p type or @c 0 if no action has been defined. * * @since 0.16 (KDE 4.10) */ Action* additionalAction( AdditionalActionType type ) const; private: Q_DECLARE_PRIVATE( ScreenAnnotation ) Q_DISABLE_COPY( ScreenAnnotation ) }; /** * \short Widget annotation. * * The widget annotation represents a widget on a page. * * @since 0.16 (KDE 4.10) */ class OKULARCORE_EXPORT WidgetAnnotation : public Annotation { public: /** * Creates a new widget annotation. */ WidgetAnnotation(); /** * Creates a new widget annotation from the xml @p description */ explicit WidgetAnnotation( const QDomNode &description ); /** * Destroys the widget annotation. */ virtual ~WidgetAnnotation(); /** * Returns the sub type of the widget annotation. */ SubType subType() const override; /** * Stores the widget annotation as xml in @p document * under the given @p parentNode. */ void store( QDomNode &parentNode, QDomDocument &document ) const override; /** * Sets the additional @p action of the given @p type. * * @since 0.16 (KDE 4.10) */ void setAdditionalAction( AdditionalActionType type, Action *action ); /** * Returns the additional action of the given @p type or @c 0 if no action has been defined. * * @since 0.16 (KDE 4.10) */ Action* additionalAction( AdditionalActionType type ) const; private: Q_DECLARE_PRIVATE( WidgetAnnotation ) Q_DISABLE_COPY( WidgetAnnotation ) }; /** * \short RichMedia annotation. * * The rich media annotation represents an video or sound on a page. * * @since 1.0 */ class OKULARCORE_EXPORT RichMediaAnnotation : public Annotation { public: /** * Creates a new rich media annotation. */ RichMediaAnnotation(); /** * Creates a new rich media annotation from the xml @p description */ explicit RichMediaAnnotation( const QDomNode &description ); /** * Destroys the rich media annotation. */ virtual ~RichMediaAnnotation(); /** * Returns the sub type of the rich media annotation. */ SubType subType() const override; /** * Stores the rich media annotation as xml in @p document * under the given @p parentNode. */ void store( QDomNode &parentNode, QDomDocument &document ) const override; /** * Gets the movie object. */ Movie* movie() const; /** * Sets the new @p movie object. */ void setMovie( Movie *movie ); /** * Sets the @p object representing the embedded file. */ void setEmbeddedFile( EmbeddedFile *object ); /** * Gets the embedded file object. */ EmbeddedFile* embeddedFile() const; private: Q_DECLARE_PRIVATE( RichMediaAnnotation ) Q_DISABLE_COPY( RichMediaAnnotation ) }; } #endif diff --git a/core/area.h b/core/area.h index b22a3ed83..bae16e9f5 100644 --- a/core/area.h +++ b/core/area.h @@ -1,876 +1,999 @@ /*************************************************************************** * Copyright (C) 2004-05 by Enrico Ros * * Copyright (C) 2005 by Piotr Szymanski * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef _OKULAR_AREA_H_ #define _OKULAR_AREA_H_ #include #include #include #include #include #include #include "global.h" #include "okularcore_export.h" class QPolygonF; class QRect; namespace Okular { class Annotation; class Action; class NormalizedShape; /** * NormalizedPoint is a helper class which stores the coordinates - * of a normalized point. Normalized means that the coordinates are - * between 0 and 1 so that it is page size independent. + * of a normalized point. * - * Example: - * The normalized point is (0.5, 0.3) + * @par Normalized Coordinate System + * @parblock + * Normalized means that the coordinates are always between 0 and 1, + * unless the point shall be outside of the reference area. * - * If you want to draw it on a 800x600 page, just multiply the x coordinate (0.5) with - * the page width (800) and the y coordinate (0.3) with the page height (600), so - * the point will be drawn on the page at (400, 180). + * The reference area is a rectangle, and all normalized points + * with coordinates of 0 or 1 describe its edges. * - * That allows you to zoom the page by just multiplying the normalized points with the - * zoomed page size. + * This allows to locate things on a reference area without knowing its + * (current or future) actual size. When the reference area is resized, + * all things which are described in normalized coordinates keep their + * proportional position on the area. + * @endparblock + * + * @par Transformation to and from Normalized Coordinates + * @parblock + * To transform normalized coordinates to coordinates on the reference area, + * just multiply them with the size of the reference area. + * + * To get normalized coordinates from a point on the reference area, + * just divide its coordinates with the size of the reference area. + * + * Many methods have parameters @c xScale and @c yScale, + * these are equal to the size of the reference area. + * @endparblock + * + * @par Normalized Coordinate System Applied to Pages + * @parblock + * Okular uses a normalized coordinate system mainly to describe + * positions on pages. + * This is useful because pages can be shown in different sizes (zoom), + * but all objects shall keep their proportional position on the page. + * + * Okular maps from page to normalized coordinates as follows: + * * Left edge of the page: x = 0 + * * Right edge of the page: x = 1 + * * Top edge of the page: y = 0 + * * Bottom edge of the page: y = 1 + * @endparblock + * + * @par Example: Draw a Point on a Page + * @parblock + * The point is given in normalized coordinates (0.5, 0.3). + * + * If you want to draw it on a 800x600 page, + * just multiply the x coordinate (0.5) with the page width (800), + * and the y coordinate (0.3) with the page height (600). + * So, the point will be drawn on the page at (400, 180). + * + * That allows you to zoom the page by just multiplying the normalized points with the + * zoomed page size. + * @endparblock + * + * @par Example: Select Text on a Page using Mouse Events + * @parblock + * The positon of all glyphs and words is stored in normalized coordinates. + * (This is what TextPage actually does.) + * Mouse press and release events are given in page coordinates (400, 180) and (600, 450), + * while the page has a size of 800x600. + * + * If you want to search all text between the mouse click and release event, + * you need their normalized coordinates. + * Just divide the x coordinates (400 and 600) by the page width (800), + * and the y coordinates (180 and 450) by the page height (600). + * So, you have to search for all glyphs between (0.5, 0.3) and (0.75, 0.75). + * + * That allows you to process all glyphs and words without + * having to keep any of their positions in sync with the page. + * @endparblock + * + * @par Geometric operations + * @parblock + * NormalizedPoint supports basic geometric operations. + * * You can transform it with a QTransform matrix. + * * With the size of the reference area, you can calculate the squared + * absolute distance to another NormalizedPoint or a line of two NormalizedPoints. + * + * NormalizedRect provides additional geometric operations for rectangles. + * @endparblock + * + * @see NormalizedRect */ class OKULARCORE_EXPORT NormalizedPoint { public: /** - * Creates a new empty normalized point. + * Creates a normalized point at (0, 0). */ NormalizedPoint(); /** * Creates a new normalized point with the normalized coordinates (@p x, @p y ). */ NormalizedPoint( double x, double y ); /** - * Creates a new normalized point with the coordinates (@p x, @p y) which are normalized - * by the scaling factors @p xScale and @p yScale. + * Creates a new normalized point from an absolute point (@p x, @p y) + * on a reference area of size @p xScale x @p yScale. */ NormalizedPoint( int x, int y, int xScale, int yScale ); /** * @internal */ NormalizedPoint& operator=( const NormalizedPoint& ); NormalizedPoint( const NormalizedPoint& ); ~NormalizedPoint(); /** * Transforms the normalized point with the operations defined by @p matrix. */ void transform( const QTransform &matrix ); /** - * Returns squared distance to point @p x @p y @p xScale @p yScale + * Returns squared distance to normalized point (@p x, @p y) + * on a reference area of size @p xScale x @p yScale. * @since 0.17 (KDE 4.11) */ double distanceSqr( double x, double y, double xScale, double yScale ) const; - /** - * @brief Calculates distance of the point @p x @p y @p xScale @p yScale to the line segment from @p start to @p end + * Returns squared distance of the normalized point (@p x, @p y) + * to the line segment from @p start to @p end + * on a reference area of size @p xScale x @p yScale. * @since 0.17 (KDE 4.11) */ static double distanceSqr( double x, double y, double xScale, double yScale, const NormalizedPoint& start, const NormalizedPoint& end ); /** * The normalized x coordinate. */ double x; /** * The normalized y coordinate. */ double y; }; /** - * NormalizedRect is a helper class which stores the coordinates - * of a normalized rect, which is a rectangle of @see NormalizedPoints. + * A NormalizedRect is a rectangle which can be defined by two NormalizedPoints. + * + * It describes a rectangular area on a reference area of undefined size. + * For more information about the normalized coordinate system, see NormalizedPoint. + * + * In Okular, NormalizedRect can be used e. g. to describe bounding boxes of TextEntity objects, + * and the highlight area of text selections. + * + * If you need to describe an area which consists of multiple rectangles, + * you can use RegularAreaRect instead. + * + * @see NormalizedPoint, RegularAreaRect, TextEntity */ class OKULARCORE_EXPORT NormalizedRect { public: /** * Creates a null normalized rectangle. * @see isNull() */ NormalizedRect(); /** * Creates a normalized rectangle with the normalized coordinates * @p left, @p top, @p right, @p bottom. * * If you need the x, y, width and height coordinates use the * following formulas: * * @li x = left * @li y = top * @li width = right - left * @li height = bottom - top + * + * @note + * The coordinates for @p left and @p top should be lower than + * @p right and @p bottom, respectively. + * At negative width or height the behaviour of some operations is undefined. */ NormalizedRect( double left, double top, double right, double bottom ); /** - * Creates a normalized rectangle of the given @p rectangle which is normalized - * by the scaling factors @p xScale and @p yScale. + * Creates a normalized rectangle from the given @p rectangle + * on a reference area of size @p xScale x @p yScale. + * + * @note + * The rectangle should have positive width and height. + * You can use e. g. QRect::normalize() to ensure this. + * At negative width or height the behaviour of some operations is undefined. */ NormalizedRect( const QRect &rectangle, double xScale, double yScale ); /** * @internal */ NormalizedRect( const NormalizedRect& ); /** * @internal */ NormalizedRect& operator=( const NormalizedRect &other ); ~NormalizedRect(); /** - * Build a normalized rect from a QRectF. + * Build a normalized rect from a QRectF, which already has normalized coordinates. */ static NormalizedRect fromQRectF( const QRectF &rect ); /** * Returns whether this normalized rectangle is a null normalized rect. */ bool isNull() const; /** - * Returns whether the normalized rectangle contains the normalized coordinates - * @p x and @p y. + * Returns whether the normalized rectangle contains the normalized point + * (@p x, @p y). */ bool contains( double x, double y ) const; /** * Returns whether the normalized rectangle intersects the @p other normalized * rectangle. */ bool intersects( const NormalizedRect &other ) const; /** * This is an overloaded member function, provided for convenience. It behaves essentially * like the above function. */ bool intersects( const NormalizedRect *other ) const; /** * Returns whether the normalized rectangle intersects an other normalized * rectangle, which is defined by @p left, @p top, @p right and @p bottom. */ bool intersects( double left, double top, double right, double bottom ) const; /** - * Returns the rectangle that accrues when the normalized rectangle is multiplyed - * with the scaling @p xScale and @p yScale. + * Returns the rectangle mapped to a reference area of @p xScale x @p yScale. */ QRect geometry( int xScale, int yScale ) const; /** * Same functionality as geometry, but the output is now rounded before typecasting to int + * * @since 0.14 (KDE 4.8) */ QRect roundedGeometry( int xScale, int yScale ) const; /** * Returns the normalized bounding rectangle of the normalized rectangle * combined with the @p other normalized rectangle. */ NormalizedRect operator|( const NormalizedRect &other ) const; /** * Sets the normalized rectangle to the normalized bounding rectangle * of itself combined with the @p other normalized rectangle. */ NormalizedRect& operator|=( const NormalizedRect &other ); /** * Returns the intersection of this normalized rectangle with the specified - * @p other. If the rects do not intersect then the result is null. + * @p other. If the rects do not intersect then the result is a null rectangle. * * @since 0.7 (KDE 4.1) */ NormalizedRect operator&( const NormalizedRect &other ) const; /** * Returns whether the normalized rectangle is equal to the @p other * normalized rectangle. */ bool operator==( const NormalizedRect &other ) const; /** * Returns the center of the rectangle * @since 0.10 (KDE 4.4) */ NormalizedPoint center() const; /** * Transforms the normalized rectangle with the operations defined by @p matrix. */ void transform( const QTransform &matrix ); /** - * Returns true if the point pt is located to the bottom of the rectangle + * Returns true if the point @p pt is located below the bottom of the rectangle * @since 0.14 (KDE 4.8) */ bool isBottom(const NormalizedPoint& pt) const { return bottom < pt.y; } /** - * Returns true if the point pt is located on the top of the rectangle + * Returns true if the point @p pt is located above the top of the rectangle * @since 0.14 (KDE 4.8) */ bool isTop(const NormalizedPoint& pt) const { return top > pt.y; } /** - * Returns true if the point pt is located under the top of the rectangle + * Returns true if the point @p pt is located below the top of the rectangle * @since 0.14 (KDE 4.8) */ bool isBottomOrLevel(const NormalizedPoint& pt) const { return top < pt.y; } /** - * Returns true if the point pt is located above the bottom of the rectangle + * Returns true if the point @p pt is located above the bottom of the rectangle * @since 0.14 (KDE 4.8) */ bool isTopOrLevel(const NormalizedPoint& pt) const { return bottom > pt.y; } /** - * Returns true if the point pt is located to the right of the left arm of rectangle + * Returns true if the point @p pt is located to the right of the left edge of the rectangle * @since 0.14 (KDE 4.8) */ bool isLeft(const NormalizedPoint& pt) const { return left < pt.x; } /** - * Returns true if the point pt is located to the left of the right arm of rectangle + * Returns true if the point @p pt is located to the left of the right edge of the rectangle * @since 0.14 (KDE 4.8) */ bool isRight(const NormalizedPoint& pt) const { return right > pt.x; } /** - * Returns the distance of the point @p x @p y @p xScale @p yScale to the closest - * edge or 0 if the point is within the rectangle + * Returns the squared distance of the normalized point (@p x, @p y) + * to the closest edge, or 0 if the point is within the rectangle; + * using a reference area of size @p xScale x @p yScale * @since 0.17 (KDE 4.11) */ double distanceSqr(double x, double y, double xScale, double yScale) const { double distX = 0; if ( x < left ) distX = left - x; else if ( x > right ) distX = x - right; double distY = 0; if ( top > y ) distY = top - y; else if (bottom < y) distY = y - bottom; return pow( distX * xScale, 2 ) + pow( distY * yScale, 2 ); } /// @since 1.4 double width() const { return right - left; } /// @since 1.4 double height() const { return bottom - top; } /** * The normalized left coordinate. */ double left; /** * The normalized top coordinate. */ double top; /** * The normalized right coordinate. */ double right; /** * The normalized bottom coordinate. */ double bottom; }; //KDE_DUMMY_QHASH_FUNCTION(NormalizedRect) /** - * @short NormalizedRect that contains a reference to an object. + * @short An area with normalized coordinates that contains a reference to an object. * - * These rects contains a pointer to a okular object (such as an action or something - * like that). The pointer is read and stored as 'void pointer' so cast is + * These areas ("rects") contain a pointer to a document object + * (such as a hyperlink, an action, or something like that). + * The pointer is read and stored as 'void pointer' so cast is * performed by accessors based on the value returned by objectType(). Objects * are reparented to this class. * * Type / Class correspondence tab: * - Action : class Action: description of an action * - Image : class Image : description of an image (n/a) * - Annotation: class Annotation: description of an annotation + * + * For more information about the normalized coordinate system, see NormalizedPoint. + * + * @see NormalizedPoint */ class OKULARCORE_EXPORT ObjectRect { public: /** * Describes the type of storable object. */ enum ObjectType { Action, ///< An action Image, ///< An image OAnnotation, ///< An annotation SourceRef ///< A source reference }; /** * Creates a new object rectangle. * * @param left The left coordinate of the rectangle. * @param top The top coordinate of the rectangle. * @param right The right coordinate of the rectangle. * @param bottom The bottom coordinate of the rectangle. * @param ellipse If true the rectangle describes an ellipse. * @param type The type of the storable object @see ObjectType. * @param object The pointer to the storable object. */ ObjectRect( double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object ); /** * This is an overloaded member function, provided for convenience. */ ObjectRect( const NormalizedRect &rect, bool ellipse, ObjectType type, void *object ); /** * This is an overloaded member function, provided for convenience. */ ObjectRect( const QPolygonF &poly, ObjectType type, void *object ); /** * Destroys the object rectangle. */ virtual ~ObjectRect(); /** * Returns the object type of the object rectangle. * @see ObjectType */ ObjectType objectType() const; /** * Returns the storable object of the object rectangle. */ const void *object() const; /** * Returns the region that is covered by the object rectangle. */ const QPainterPath ®ion() const; /** * Returns the bounding rect of the object rectangle for the * scaling factor @p xScale and @p yScale. */ virtual QRect boundingRect( double xScale, double yScale ) const; /** - * Returns whether the object rectangle contains the point @p x, @p y for the - * scaling factor @p xScale and @p yScale. + * Returns whether the object rectangle contains the point with absolute coordinates + * (@p x, @p y) at a page size of @p xScale x @p yScale. */ virtual bool contains( double x, double y, double xScale, double yScale ) const; /** * Transforms the object rectangle with the operations defined by @p matrix. */ virtual void transform( const QTransform &matrix ); /** - * Returns the square of the distance between the object and the point @p x, @p y - * for the scaling factor @p xScale and @p yScale. + * Returns the squared distance between the object + * and the point with + * normalized coordinates (@p x, @p y) + * at a page size of @p xScale x @p yScale. * * @since 0.8.2 (KDE 4.2.2) */ // FIXME this should most probably be a virtual method double distanceSqr( double x, double y, double xScale, double yScale ) const; protected: ObjectType m_objectType; void * m_object; QPainterPath m_path; QPainterPath m_transformedPath; }; /** * This class describes the object rectangle for an annotation. */ class OKULARCORE_EXPORT AnnotationObjectRect : public ObjectRect { public: /** * Creates a new annotation object rectangle with the * given @p annotation. */ explicit AnnotationObjectRect( Annotation *annotation ); /** * Destroys the annotation object rectangle. */ virtual ~AnnotationObjectRect(); /** * Returns the annotation object of the annotation object rectangle. */ Annotation *annotation() const; /** * Returns the bounding rect of the annotation object rectangle for the * scaling factor @p xScale and @p yScale. */ QRect boundingRect( double xScale, double yScale ) const override; /** * Returns whether the annotation object rectangle contains the point @p x, @p y for the * scaling factor @p xScale and @p yScale. */ bool contains( double x, double y, double xScale, double yScale ) const override; /** * Transforms the annotation object rectangle with the operations defined by @p matrix. */ void transform( const QTransform &matrix ) override; private: Annotation * m_annotation; }; /** * This class describes the object rectangle for a source reference. */ class OKULARCORE_EXPORT SourceRefObjectRect : public ObjectRect { friend class ObjectRect; public: /** * Creates a new source reference object rectangle. * * @param point The point of the source reference. * @param reference The storable source reference object. */ SourceRefObjectRect( const NormalizedPoint& point, void *reference ); /** * Returns the bounding rect of the source reference object rectangle for the * scaling factor @p xScale and @p yScale. */ QRect boundingRect( double xScale, double yScale ) const override; /** * Returns whether the source reference object rectangle contains the point @p x, @p y for the * scaling factor @p xScale and @p yScale. */ bool contains( double x, double y, double xScale, double yScale ) const override; private: NormalizedPoint m_point; }; /** * This class is an object rect that doesn't own the given pointer, i.e. won't delete it on destruction * @since 1.7 */ class OKULARCORE_EXPORT NonOwningObjectRect : public ObjectRect { public: NonOwningObjectRect( double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object ); ~NonOwningObjectRect(); }; /// @cond PRIVATE /** @internal */ /** @internal */ template T* givePtr( T& t ) { return &t; } /** @internal */ template T& deref( T& t ) { return t; } /// @endcond /** - * @short A regular area of NormalizedShape which normalizes a Shape + * @short An area with normalized coordinates, consisting of NormalizedShape objects. + * + * This is a template class to describe an area which consists of + * multiple shapes of the same type, intersecting or non-intersecting. + * The coordinates are normalized, and can be mapped to a reference area of defined size. + * For more information about the normalized coordinate system, see NormalizedPoint. * * Class NormalizedShape \b must have the following functions/operators defined: - * - bool contains( double, double ) + * - bool contains( double, double ), whether it contains the given NormalizedPoint * - bool intersects( NormalizedShape ) * - bool isNull() - * - Shape geometry( int, int ) - * - operator|=( NormalizedShape ) which unite two NormalizedShape's + * - Shape geometry( int, int ), which maps to the reference area + * - operator|=( NormalizedShape ), which unites two NormalizedShape's + * + * @see RegularAreaRect, NormalizedPoint */ template class RegularArea : public QList { public: /** - * Returns whether the regular area contains the - * normalized point @p x, @p y. + * Returns whether this area contains the normalized point (@p x, @p y). */ bool contains( double x, double y ) const; /** - * Returns whether the regular area contains the - * given @p shape. + * Returns whether this area contains a NormalizedShape object that equals @p shape. + * + * @note + * The original NormalizedShape objects can be lost if simplify() was called. */ bool contains( const NormalizedShape& shape ) const; /** - * Returns whether the regular area intersects with the given @p area. + * Returns whether this area intersects with the given @p area. */ bool intersects( const RegularArea *area ) const; /** * Returns whether the regular area intersects with the given @p shape. */ bool intersects( const NormalizedShape& shape ) const; /** - * Appends the given @p area to the regular area. + * Appends the given @p area to this area. */ void appendArea( const RegularArea *area ); /** - * Appends the given @p shape to the regular area. + * Appends the given @p shape to this area. */ void appendShape( const NormalizedShape& shape, MergeSide side = MergeAll ); /** - * Simplifies the regular area by merging its intersecting subareas. + * Simplifies this regular area by merging its intersecting subareas. + * This might change the effective geometry of this area. */ void simplify(); /** * Returns whether the regular area is a null area. */ bool isNull() const; /** - * Returns the subareas of the regular areas as shapes for the given scaling factor - * @p xScale and @p yScale, translated by @p dx and @p dy. + * Returns the subareas of this regular area + * mapped to a reference area of size @p xScale x @p yScale, + * then translated by @p dx and @p dy. */ QList geometry( int xScale, int yScale, int dx = 0, int dy = 0 ) const; /** * Transforms the regular area with the operations defined by @p matrix. */ void transform( const QTransform &matrix ); }; template void RegularArea::simplify() { #ifdef DEBUG_REGULARAREA int prev_end = this->count(); #endif int end = this->count() - 1, x = 0; for ( int i = 0; i < end; ++i ) { if ( givePtr( (*this)[x] )->intersects( deref( (*this)[i+1] ) ) ) { deref((*this)[x]) |= deref((*this)[i+1]); this->removeAt( i + 1 ); --end; --i; } else { x=i+1; } } #ifdef DEBUG_REGULARAREA qCDebug(OkularCoreDebug) << "from" << prev_end << "to" << this->count(); #endif } template bool RegularArea::isNull() const { if ( this->isEmpty() ) return true; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) if ( !givePtr( *it )->isNull() ) return false; return true; } template bool RegularArea::intersects( const NormalizedShape& rect ) const { if ( this->isEmpty() ) return false; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) if ( !givePtr( *it )->isNull() && givePtr( *it )->intersects( rect ) ) return true; return false; } template bool RegularArea::intersects( const RegularArea *area ) const { if ( this->isEmpty() ) return false; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) { typename QList::const_iterator areaIt = area->begin(), areaItEnd = area->end(); for ( ; areaIt != areaItEnd; ++areaIt ) { if ( !( *it ).isNull() && ( *it ).intersects( *areaIt ) ) return true; } } return false; } template void RegularArea::appendArea( const RegularArea *area ) { typename QList::const_iterator areaIt = area->begin(), areaItEnd = area->end(); for ( ; areaIt != areaItEnd; ++areaIt ) this->append( *areaIt ); } template void RegularArea::appendShape( const NormalizedShape& shape, MergeSide side ) { int size = this->count(); // if the list is empty, adds the shape normally if ( size == 0 ) { this->append( shape ); } else { bool intersection = false; NormalizedShape& last = (*this)[size - 1]; #define O_LAST givePtr( last ) # define O_LAST_R O_LAST->right # define O_LAST_L O_LAST->left # define O_LAST_T O_LAST->top # define O_LAST_B O_LAST->bottom #define O_NEW givePtr( shape ) # define O_NEW_R O_NEW->right # define O_NEW_L O_NEW->left # define O_NEW_T O_NEW->top # define O_NEW_B O_NEW->bottom switch ( side ) { case MergeRight: intersection = ( O_LAST_R >= O_NEW_L ) && ( O_LAST_L <= O_NEW_R ) && ( ( O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B ) || ( O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B ) ); break; case MergeBottom: intersection = ( O_LAST_B >= O_NEW_T ) && ( O_LAST_T <= O_NEW_B ) && ( ( O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L ) || ( O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L ) ); break; case MergeLeft: intersection = ( O_LAST_L <= O_NEW_R ) && ( O_LAST_R >= O_NEW_L ) && ( ( O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B ) || ( O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B ) ); break; case MergeTop: intersection = ( O_LAST_T <= O_NEW_B ) && ( O_LAST_B >= O_NEW_T ) && ( ( O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L ) || ( O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L ) ); break; case MergeAll: intersection = O_LAST->intersects( shape ); break; } #undef O_LAST # undef O_LAST_R # undef O_LAST_L # undef O_LAST_T # undef O_LAST_B #undef O_NEW # undef O_NEW_R # undef O_NEW_L # undef O_NEW_T # undef O_NEW_B // if the new shape intersects with the last shape in the list, then // merge it with that and delete the shape if ( intersection ) { deref((*this)[size - 1]) |= deref( shape ); } else this->append( shape ); } } template bool RegularArea::contains( double x, double y ) const { if ( this->isEmpty() ) return false; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) if ( ( *it ).contains( x, y ) ) return true; return false; } template bool RegularArea::contains( const NormalizedShape& shape ) const { if ( this->isEmpty() ) return false; return QList::contains( shape ); } template QList RegularArea::geometry( int xScale, int yScale, int dx, int dy ) const { if ( this->isEmpty() ) return QList(); QList ret; Shape t; typename QList::const_iterator it = this->begin(), itEnd = this->end(); for ( ; it != itEnd; ++it ) { t = givePtr( *it )->geometry( xScale, yScale ); t.translate( dx, dy ); ret.append( t ); } return ret; } template void RegularArea::transform( const QTransform &matrix ) { if ( this->isEmpty() ) return; for ( int i = 0; i < this->count(); ++i ) givePtr( (*this)[i] )->transform( matrix ); } +/** + * This is a list of NormalizedRect, to describe an area consisting of + * multiple rectangles using normalized coordinates. + * + * This area can be mapped to a reference area, resulting in a list of QRects. + * For more information about the normalized coordinate system, see NormalizedPoint. + * + * Okular uses this area e. g. to describe a text highlight area, + * which consists of multiple, intersecting or non-intersecting rectangles. + * + * @see NormalizedRect, NormalizedPoint + */ class OKULARCORE_EXPORT RegularAreaRect : public RegularArea< NormalizedRect, QRect > { public: RegularAreaRect(); RegularAreaRect( const RegularAreaRect& rar ); ~RegularAreaRect(); RegularAreaRect& operator=( const RegularAreaRect& rar ); private: class Private; Private * const d; }; /** - * This class stores the coordinates of a highlighting area - * together with the id of the highlight owner and the color. + * This class stores the geometry of a highlighting area in normalized coordinates, + * together with highlighting specific information. */ class HighlightAreaRect : public RegularAreaRect { public: /** * Creates a new highlight area rect with the coordinates of * the given @p area. */ explicit HighlightAreaRect( const RegularAreaRect *area = nullptr ); /** * The search ID of the highlight owner. */ int s_id; /** * The color of the highlight. */ QColor color; }; } uint qHash(const Okular::NormalizedRect& r, uint seed = 0); #ifndef QT_NO_DEBUG_STREAM /** * Debug operator for normalized @p point. */ OKULARCORE_EXPORT QDebug operator<<( QDebug str, const Okular::NormalizedPoint &point ); /** * Debug operator for normalized @p rect. */ OKULARCORE_EXPORT QDebug operator<<( QDebug str, const Okular::NormalizedRect &rect ); #endif #endif