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 |
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:
Editor screen after instance of StarDecorator class is assigned to the editor:
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.
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. |