Logo Search packages:      
Sourcecode: inkscape version File versions  Download package

svg-profile.h

#ifndef __INK_SVG_PROFILE_H__
#define __INK_SVG_PROFILE_H__
/*
 * A class for managing which SVG Profiles are used.
 *
 * Authors:
 *   Ted Gould <ted@gould.cx>
 *
 * Copyright (C) 2004 Authors
 *
 * Released under GNU GPL, read the file 'COPYING' for more information
 */

namespace Inkscape {

/**
    \brief  A class that contains information on which SVG profiles are
            marked for the object.

    The basic functionality here is to allow marking of which profiles
    are supported or required by some other object.  The basic
    implementation of that is a bitfield, a data type that has bits
    to be able to be set depending on whether or not that particular
    feature is available.  This implementation is a little more complex
    for a coulple of reasons.

    The first reason for making it be more complex is to make it into
    a nice C++ friendly class, where the actual bits aren't required
    by the calling application.  This is accomplished by use of the
    \c SvgProfileType enum, and having the various fields in there.

    The second reason that this is more complex is that it is reasonable
    that the enum will grow to be greater than the native integer of
    a given system.  As more profiles and distinctions are made, there
    will have to be more entries in the enum.  In order to combat this,
    the \c BitField class was created.  This creates consistent operations
    independent of how many integers are used to represent the particular
    bitfield.
 
    The entire class has been optimized for inlining and compiler reduction
    of code.  All entires should allow being put in a structure or other
    static allocation.  For most operations, simple and/or instructions
    in the processor is required after optimization.

    Adding additional profiles to the class is as easy as adding entires
    into the enum.  Adding additional aggregates requires adding to the
    enum, and adding the aggregate into the constructor for the class.
*/
00049 class SvgProfile {
public:
    /** \brief  The enum listing all the different profiles supported, and
                some aggregate ones supported.

        \note  This \c enum should not be used for anything other than passing
               data into the constructor of \c SvgProfile.  The optimization
               of the constructor is best when it is passed a static value.
               So, passing this enum through a function, and then constructing
               the \c SvgProfile would be less than ideal.  Plus, as far as
               memory goes, today, they take up the same amount of memory.
    */
00061     enum SvgProfileType {
00062         BASIC_OPERATION = 0,  /**< This describes a feature that is part
                                   of the basic functionality of Inkscape
                                   itself.  This would be like save or open. */
00065         SVG_BASE_1_0,         /**< The base SVG spec version 1.0 */
00066         SVG_BASE_1_1,         /**< The base SVG spec version 1.1 */
00067         SVG_BASE_1_2,         /**< The base SVG spec version 1.2 */
00068         SVG_BASE_2_0,         /**< The base SVG spec version 2.0 */

00070         SVG_MOBILE_TINY_1_1,  /**< The mobile SVG spec Tiny profile version 1.1 */
00071         SVG_MOBILE_BASIC_1_1, /**< The mobile SVG spec Basic profile version 1.1 */
00072         SVG_MOBILE_TINY_1_2,  /**< The mobile SVG spec Tiny profile version 1.2 */
00073         SVG_MOBILE_BASIC_1_2, /**< The mobile SVG spec Basic profile version 1.2 */

00075         SVG_PRINT_1_1,        /**< */

00077         PROFILE_UNIQUE_CNT,   /**< A marker to seperate between the entires
                                   that are unique, and those which are
                                   aggregates of them. */

00081         SVG_BASE_ALL,         /**< Every version of the SVG Base spec */
00082         SVG_MOBILE_ALL,       /**< Every version and profile in SVG Mobile */
00083         SVG_TINY_ALL,         /**< Every version of the tiny profile in SVG Mobile */
00084         SVG_BASIC_ALL,        /**< Every version of the basic profile in SVG Mobile */
00085         ALL                   /**< All, everything, basically doesn't tell you anything at all */
    };

private:
    /** \brief  The core of the \c SvgProfile class, this implements a
                bitfield which can be several integers large with standard
                operations independent of size. */
00092     class BitField {
        /** \brief A quick way identify the number of bits in an integer. */
        #define  BITS_IN_INT (sizeof(int) * 8)
        /** \brief The size of the array which is being used. */
        #define  ARRAY_SIZE  (((PROFILE_UNIQUE_CNT - 1) / BITS_IN_INT) + 1)

            /** \brief The actuall array holding the bitfield. */
00099             unsigned int bits[ARRAY_SIZE];

        public:
            /** \brief Constructor for the bitfield, it clears the \c bits
                       array by setting things to zero. */
00104             inline BitField(void) {
                for (int i = 0; i < ARRAY_SIZE; i++) {
                    bits[i] = 0;
                }
            }

            /** \brief Constructs a bitfield by passing in another array
                       describing how the bits should look.  The function
                       just copies the array into \c bits. */
00113             inline BitField(unsigned int in_bits[ARRAY_SIZE]) {
                for (int i = 0; i < ARRAY_SIZE; i++) {
                    bits[i] = in_bits[i];
                }
            }

            /** \brief The equals operator, but it doesn't do quite that.
                       This function checks to see if there are bits that
                       are similarly high in both bitfields. */
00122             inline bool operator == (const BitField &in_field) const {
                for (int i = 0; i < ARRAY_SIZE; i++) {
                    if (bits[i] & in_field.bits[i] != 0)
                        return true;
                }
                return false;
            }

            /** \brief A convience function to set a particular bit in the
                       bitfield

                This function first find which integer the bit is in by
                dividing by \c BITS_IN_INT and then which bit in the
                integer by getting the modulus.  The selected integer is
                the \c |= with a \c 1 shifted left by the possition.
            */
00138             inline void set (const unsigned int pos) {
                unsigned int array_pos = pos / BITS_IN_INT;
                unsigned int bit_pos   = pos % BITS_IN_INT;
                bits[array_pos] |= 1 << bit_pos;
            }

            /** \brief Does a bitwise \c OR on two bitfields.  It does
                       this for the entire \c bits array. */
00146             inline BitField operator | (const BitField &other) const {
                unsigned int local_bits[ARRAY_SIZE];

                for (int i = 0; i < ARRAY_SIZE; i++) {
                    local_bits[i] = bits[i] | other.bits[i];
                }

                return BitField(local_bits);
            }

            /** \brief  Causes one \c BitField to take on the values
                        stored in a different bitfield. */
00158             inline BitField & operator = (const BitField &other) {
                for (int i = 0; i < ARRAY_SIZE; i++) {
                    bits[i] = other.bits[i];
                }

                return *this;
            }

            /** \brief  Does a logical \c OR of the bitfield with another
                        bitfield.  It does this by using \c |=. */
00168             inline BitField & operator |= (const BitField &other) {
                for (int i = 0; i < ARRAY_SIZE; i++) {
                    bits[i] |= other.bits[i];
                }
                return *this;    
            }

        #undef BITS_IN_INT
        #undef ARRAY_SIZE
    };
    
    /** \brief The actual data stored on the profile. */
00180     BitField _profile;

    /**
        \brief  Create an SvgProfile with an already created bitfield
        \param  in_field  The bitfield that should be used in the profile

        This function just copies the incoming bitfield into the one
        which is allocated for this.
    */
00189     inline SvgProfile (const BitField &in_field) {
        _profile = in_field;
    }

public:
    /** \brief A constructor for \c SvgProfile which sets up the bitfield
               based on the \c SvgProfileType getting passed in.

        This function has basically two different modes of operation
        depending on whether the requested value is a pure profile or
        and aggregate.  If it is pure, then that bit is set in \c _profile
        and the function exits.  Otherwise a case statement is used to
        determine which aggregate is called, and then setting all of
        the bits for that aggregate.
    */
00204     inline SvgProfile (SvgProfileType type) {
        if (type < PROFILE_UNIQUE_CNT) {
            _profile.set(type);
        } else {
            /* Okay, so this could be done by OR'ing a bunch of these
               together, but I thought that would reduce the chance of
               the compiler actually figuring it all out and optimizing
               everything.  This is already getting pretty complex. */
            switch (type) {
                case SVG_BASE_ALL:
                    _profile.set(SVG_BASE_1_0);
                    _profile.set(SVG_BASE_1_1);
                    _profile.set(SVG_BASE_1_2);
                    _profile.set(SVG_BASE_2_0);
                    break;
                case SVG_BASIC_ALL:
                    _profile.set(SVG_MOBILE_BASIC_1_1);
                    _profile.set(SVG_MOBILE_BASIC_1_2);
                    break;
                case SVG_TINY_ALL:
                    _profile.set(SVG_MOBILE_TINY_1_1);
                    _profile.set(SVG_MOBILE_TINY_1_2);
                    break;
                case SVG_MOBILE_ALL:
                    _profile.set(SVG_MOBILE_BASIC_1_1);
                    _profile.set(SVG_MOBILE_BASIC_1_2);
                    _profile.set(SVG_MOBILE_TINY_1_1);
                    _profile.set(SVG_MOBILE_TINY_1_2);
                    break;
                case ALL:
                    _profile.set(SVG_BASE_1_0);
                    _profile.set(SVG_BASE_1_1);
                    _profile.set(SVG_BASE_1_2);
                    _profile.set(SVG_BASE_2_0);

                    _profile.set(SVG_MOBILE_BASIC_1_1);
                    _profile.set(SVG_MOBILE_BASIC_1_2);

                    _profile.set(SVG_MOBILE_TINY_1_1);
                    _profile.set(SVG_MOBILE_TINY_1_2);
                    break;
            };
        }
        return;    
    };

    /** \brief A function to check equality of two \c SvgProfiles.
               It doesn't quite check equality though, it more ensures
               that there is a profile supported by both objects.  This
               would be similar to: (a & b) != 0 in a standard bitfield
               impelemtation.  But is done this way for simplicity. */
00255     inline bool operator == (const SvgProfile &in_profile) const {
        return _profile == in_profile._profile;
    };

    /** \brief A function allow combining of \c SvgProfiles with each
               other into a larger \c SvgProfile. */
00261     inline SvgProfile operator | (const SvgProfile &other) const {
        return SvgProfile(_profile | other._profile);
    }

    /** \brief A quick way to add additional profiles to the currently
               allocated object. */
00267     inline SvgProfile & operator |= (const SvgProfile &other) {
        _profile |= other._profile;
        return *this;
    }
};


}  /* namespace Inkscape */

#endif /* __INK_SVG_PROFILE_H__ */

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :

Generated by  Doxygen 1.6.0   Back to index