Code

Avoid crash by uninitialized perspectives.
[inkscape.git] / src / text-tag-attributes.h
1 #ifndef INKSCAPE_TEXT_TAG_ATTRIBUTES_H
2 #define INKSCAPE_TEXT_TAG_ATTRIBUTES_H
4 #include <vector>
5 #include <glib/gtypes.h>
6 #include "libnrtype/Layout-TNG.h"
7 #include "svg/svg-length.h"
9 namespace Inkscape {
10 namespace XML {
11 class Node;
12 }
13 }
16 /** \brief contains and manages the attributes common to all types of text tag
18 The five attributes x, y, dx, dy and rotate (todo: textlength, lengthadjust)
19 are permitted on all of text, tspan and textpath elements so we need a class
20 to abstract the management of those attributes from the actual type of the
21 element.
22 */
23 class TextTagAttributes {
24 public:
25     TextTagAttributes() {}
26     TextTagAttributes(Inkscape::Text::Layout::OptionalTextTagAttrs const &attrs)
27         : attributes(attrs) {}
29     /// Fill in all the fields of #attributes from the given node.
30     void readFrom(Inkscape::XML::Node const *node);
32     /** Process the parameters from the set() function of SPObject.
33         Returns true if \a key was a recognised attribute. */
34     bool readSingleAttribute(unsigned key, gchar const *value);
36     /// Write out all the contents of #attributes to the given node.
37     void writeTo(Inkscape::XML::Node *node) const;
39     /** For tspan role=line elements we should not use the set x,y
40     coordinates since that would overrule the values calculated by the
41     text layout engine, however if there are more than one element in
42     the x or y vectors we can presume that the user set them and hence
43     they should be copied. This function detects that condition so the
44     \a use_xy parameter to mergeInto() can be set correctly. */
45     bool singleXYCoordinates() const;
47     /** Returns false if all of the vectors are zero length. */
48     bool anyAttributesSet() const;
50     /** Implements the rules for overlaying the contents of the class
51     (treated as the child object) on top of previously existing
52     attributes from \a parent_attrs using the rules described in
53     SVG 1.1 section 10.5. \a parent_attrs_offset can be used to require
54     that only fields from \a parent_attrs starting at that index will
55     be used. Basically, the algorithm is that if a child attribute
56     exists that will be used, otherwise the parent attribute will be used,
57     otherwise the vector will end. */
58     void mergeInto(Inkscape::Text::Layout::OptionalTextTagAttrs *output, Inkscape::Text::Layout::OptionalTextTagAttrs const &parent_attrs, unsigned parent_attrs_offset, bool copy_xy, bool copy_dxdyrotate) const;
60     /** Deletes all the values from all the vectors beginning at
61     \a start_index and extending for \a n fields. This is what you want
62     to do when deleting characters from the corresponding text. */
63     void erase(unsigned start_index, unsigned n);
65     /** Inserts \a n new values in all the stored vectors at \a
66     start_index. This is what you want to do when inserting characters
67     in the corresponding text. If a vector is shorter than \a start_index
68     it will not be extended (the defaults are fine). dx, dy and rotate
69     will be extended with zero values, x and y will be extended with
70     linearly interpolated values. TODO: The inserted values should probably
71     be unset but sp_svg_length_list_read() can't cope with that. */
72     void insert(unsigned start_index, unsigned n);
74     /** Divides the stored attributes into two, at the given index. The
75     first section (0..index-1) stay in this object, the second section
76     (index..end) go in \a second. This function is generally used when
77     line breaking. */
78     void split(unsigned index, TextTagAttributes *second);
80     /** Overwrites all the attributes contained in this object with the
81     given parameters by putting \a first at the beginning, then the
82     contents of \a second after \a second_index. */
83     void join(TextTagAttributes const &first, TextTagAttributes const &second, unsigned second_index);
85     /** Applies the given transformation to the stored coordinates. Pairs
86     of x and y coordinates are multiplied by the matrix and the dx and dy
87     vectors are multiplied by the given parameters. rotate is not altered.
88     If \a extend_zero_length is true, then if the x or y vectors are empty
89     they will be made length 1 in order to store the newly calculated
90     position. */
91     void transform(Geom::Matrix const &matrix, double scale_x, double scale_y, bool extend_zero_length = false);
93     /** Adds the given values to the dx and dy vectors at the given
94     \a index. The vectors are extended if necessary. */
95     void addToDxDy(unsigned index, Geom::Point const &adjust);
97     /** Adds the given value to the rotate vector at the given \a index. The
98     vector is extended if necessary. Delta is measured in degrees, clockwise
99     positive. */
100     void addToRotate(unsigned index, double delta);
102     /** Returns the first coordinates in the x and y vectors. If either
103     is zero length, 0.0 is used for that coordinate. */
104     Geom::Point firstXY() const;
106     /** Sets the first coordinates in the x and y vectors. */
107     void setFirstXY(Geom::Point &point);
109 private:
110     /// This holds the actual values.
111     Inkscape::Text::Layout::OptionalTextTagAttrs attributes;
113     /** Does the reverse of readSingleAttribute(), converting a vector<> to
114     its SVG string representation and writing it in to \a node. Used by
115     writeTo(). */
116     static void writeSingleAttribute(Inkscape::XML::Node *node, gchar const *key, std::vector<SVGLength> const &attr_vector);
118     /** Does mergeInto() for one member of #attributes. If \a overlay_list
119     is NULL then it does a simple copy of parent elements, starting at
120     \a parent_offset. */
121     static void mergeSingleAttribute(std::vector<SVGLength> *output_list, std::vector<SVGLength> const &parent_list, unsigned parent_offset, std::vector<SVGLength> const *overlay_list = NULL);
123     /// Does the work for erase().
124     static void eraseSingleAttribute(std::vector<SVGLength> *attr_vector, unsigned start_index, unsigned n);
126     /// Does the work for insert().
127     static void insertSingleAttribute(std::vector<SVGLength> *attr_vector, unsigned start_index, unsigned n, bool is_xy);
129     /// Does the work for split().
130     static void splitSingleAttribute(std::vector<SVGLength> *first_vector, unsigned index, std::vector<SVGLength> *second_vector, bool trimZeros);
132     /// Does the work for join().
133     static void joinSingleAttribute(std::vector<SVGLength> *dest_vector, std::vector<SVGLength> const &first_vector, std::vector<SVGLength> const &second_vector, unsigned second_index);
134 };
137 #endif /* !INKSCAPE_TEXT_TAG_ATTRIBUTES_H */
139 /*
140   Local Variables:
141   mode:c++
142   c-file-style:"stroustrup"
143   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
144   indent-tabs-mode:nil
145   fill-column:99
146   End:
147 */
148 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :