fe::ISubstringDecorator Class Reference
[Ferry Core library]

Interface to provide custom decoration of the part of a text line. More...

Inheritance diagram for fe::ISubstringDecorator:

fe::ISubstringFiller

List of all members.

Classes

struct  SubstrInfo
 Visual attributes of custom decorated part of a text line. More...

Public Member Functions

SubstrInfo getSubstrInfo (FeHandle *editor, const DecorMetrics &dm, unsigned x, Substring substr) const

Protected Member Functions

virtual void UC_DLL_CALL getSubstrInfoImpl (FeHandle *editor, const DecorMetrics &dm, unsigned x, Substring substr, SubstrInfo &res) const =0


Detailed Description

Interface to provide custom decoration of the part of a text line.

Should be used when some complex text decoration is needed and it can't be described with fe::TextStyle. E.g.: replace text representation of emoticons with graphics, i.e. instruct editor to draw images instead of ':-)', ':-(' and similar substrings.

Sample fe::ISubstringDecorator implementation that draws a star figure:

#include <math.h>
#include "fe/ferry.h"


class StarSubstringDecorator : public fe::ISubstringDecorator
{
UC_DLL_INTERFACE_IMPL(ISubstringFiller)
private:
    double      sinA_;
    double      cosA_;
    double      sinB_;
    double      cosB_;
    SubstrInfo  dims_;

public:
    //
    // If 'starSize' parameter is not '0' then the star figure has fixed size
    // and fits in a circle with the diameter equal to the value of 'starSize'
    // parameter. Otherwise height of star figure is variable and is equal
    // to the height of an enclosing line segment or 100px whatever is less.
    //
    explicit StarSubstringDecorator(unsigned starSize)
    {
        dims_.height = starSize;
        dims_.ascent = unsigned(dims_.height * 0.7);

        if(starSize)
        {
            dims_.width = starSize;
        }
        else
        {
            dims_.width = 100;
        }

        // precalculate constants
        const double pi     = 3.1415926535;
        const double angleA = 2 * pi / 5;
        const double angleB = angleA / 2;

        sinA_ = sin(angleA);
        cosA_ = cos(angleA);
        sinB_ = sin(angleB);
        cosB_ = cos(angleB);
    }

// fe::ISubstringDecorator implementation
protected:
    virtual void UC_DLL_CALL
    getSubstrInfoImpl(
        fe::FeHandle*           editor,
        const fe::DecorMetrics& dm,
        unsigned                x,
        fe::Substring           substr,
        SubstrInfo&             res) const
    {
        res = dims_;
    }

public:
    virtual void UC_DLL_CALL
    paint(
        fe::FeHandle*                           editor,
        const fe::DecorMetrics&                 dm,
        fe::Substring                           substr,
        fe::PlatformTypes::graphics_handle_type g,
        int                                     x,
        int                                     y,
        unsigned                                width,
        unsigned                                lineHeight,
        unsigned                                lineAscent) const
    {
        int a = dims_.height;
        if(0 == a)
        {
            if(width < lineHeight)
            {
                a = width;
            }
            else
            {
                a = lineHeight;
            }
        }

        // r - outer star cicle radius
        double r = a / 2;
        // ox, oy - top left origin of the outer star bbox
        double ox = x + 0.5 * (width - a);
        double oy = y + 0.5 * (lineHeight - (r + r * cosB_));

        // ir - inner star cicle radius (scale factor is an approximation)
        double ir = r * 0.4;
        // ix, iy - top left origin of the inner star bbox
        double ix = ox + r - ir;
        double iy = oy + r - ir;

#ifdef _WIN32
        // no error checks for simplicity

        int savedDC = ::SaveDC(g);

        {   // fill background
            HBRUSH  bgBrush = ::CreateSolidBrush(RGB(255, 255, 0));

            RECT rect = { x, y, x + width, y + lineHeight };
            ::FillRect(g, &rect, bgBrush);

            ::DeleteObject(bgBrush);
        }

        // draw star

        const POINT vertices[] =
        {
            { LONG(ox + r), LONG(oy) },
            { LONG(ix + ir + ir * sinB_), LONG(iy + ir - ir * cosB_) },

            { LONG(ox + r + r * sinA_), LONG(oy + r - r * cosA_) },
            { LONG(ix + ir + ir * sinA_), LONG(iy + ir + ir * cosA_) },

            { LONG(ox + r + r * sinB_), LONG(oy + r + r * cosB_) },
            { LONG(ix + ir), LONG(iy + ir + ir) },

            { LONG(ox + r - r * sinB_), LONG(oy + r + r * cosB_) },
            { LONG(ix + ir - ir * sinA_), LONG(iy + ir + ir * cosA_) },

            { LONG(ox + r - r * sinA_), LONG(oy + r - r * cosA_) },
            { LONG(ix + ir - ir * sinB_), LONG(iy + ir - ir * cosB_) },

            { LONG(ox + r), LONG(oy) },
        };

        HBRUSH  fillBrush   = ::CreateSolidBrush(RGB(255, 0, 0));
        HPEN    borderPen   = ::CreatePen(PS_SOLID, 1, RGB(0, 0, 0));

        ::SelectObject(g, borderPen);

        HRGN rgn =
            ::CreatePolygonRgn(
                vertices,
                sizeof(vertices) / sizeof(vertices[0]) - 1,
                WINDING);

        ::FillRgn(g, rgn, fillBrush);

        ::Polyline(g, vertices, sizeof(vertices) / sizeof(vertices[0]));

        ::RestoreDC(g, savedDC);

        ::DeleteObject(rgn);
        ::DeleteObject(borderPen);
        ::DeleteObject(fillBrush);

#endif // #ifdef _WIN32
    }
};

Sample fe::IDecorator implementation that uses StarSubstringDecorator to replace all 'A' and 'a' letters in text with star figures:

#include "fe/ferry.h"


class StarDecorator : public fe::DecoratorStub
{
    StarSubstringDecorator decor_A_;
    StarSubstringDecorator decor_a_;

public:
    StarDecorator(): decor_A_(40), decor_a_(0)
    {
    }

// fe::DecoratorStub overridings
public:
    virtual bool UC_DLL_CALL
    decorate(
        fe::FeHandle*           editor,
        unsigned                line,
        const fe::byte_type*    str,
        unsigned                len,
        fe::IDecoratorListener& dl)
    {
        fe::TextStyle ts(fe::TextStyle::makeStyle(0, 0x0));

        for(const fe::byte_type* estr = str + len; str != estr; ++str)
        {
            switch(*str)
            {
            case 'A':
                dl.onSubstringDecorated(
                    1, fe::DecorMetrics(decor_A_), "sample:star_fixed");
                break;

            case 'a':
                dl.onSubstringDecorated(
                    1, fe::DecorMetrics(decor_a_), "sample:star_auto");
                break;

            default:
                dl.onSubstringDecorated(
                    1, fe::DecorMetrics(ts), "sample:other");
                break;
            }
        }

        return true;
    }
};

Editor screen before instance of StarDecorator class is assigned to the editor with the fe::IEditorFacade::setDecorator() call:

star_decorator.set=false.png

Editor screen after instance of StarDecorator class is assigned to the editor:

star_decorator.set=true.png

See also:
fe::DecorMetrics

Member Function Documentation

virtual void UC_DLL_CALL fe::ISubstringDecorator::getSubstrInfoImpl ( FeHandle *  editor,
const DecorMetrics dm,
unsigned  x,
Substring  substr,
SubstrInfo res 
) const [protected, pure virtual]

SubstrInfo fe::ISubstringDecorator::getSubstrInfo ( FeHandle *  editor,
const DecorMetrics dm,
unsigned  x,
Substring  substr 
) const [inline]

Returns visual attributes of the given part of a text line segment decorated with this substring decorator.

Parameters:
editor editor calling the method; never 0;
dm original decoration applied to the text line segment referenced with the substr parameter;
x X-coordinate of the origin starting from which the substr is rendered; the value is relative to the left border of the bounding box of the text line segment the substr belongs to;
substr the part of a text line to get attributes for.


The documentation for this class was generated from the following file:

Generated on Tue Nov 18 21:08:23 2008 for Ferry by doxygen 1.5.7.1
http://sourceforge.net