#pragma once #include #include #include "SharedPtr.h" using std::pair; using std::stack; #ifdef TME_RENDERER_COMMAND_DEBUG #define SEND_TO_STACK(command) RendererCommandStack::sendCommand(command) #else #define SEND_TO_STACK(command) #endif #define USE_NEW_COMMAND #ifdef USE_NEW_COMMAND #define __UUIDOF__IAVSRENDERER2 __uuidof(IAVSRenderer2) #else #define __UUIDOF__IAVSRENDERER2 __uuidof(IAVSFontManager) #endif class RendererCommand { public: enum RendererCommandType { BEGIN, END }; enum RendererCommandName { COMMON, HEADER, TABLE, BLOCK }; private: RendererCommandType _type; RendererCommandName _name; bool _added; public: RendererCommand(const RendererCommandName& name = COMMON , const RendererCommandType& type = BEGIN) : _name(name), _type(type) , _added(false) { } public: virtual void send(IAVSRenderer2* renderer) = 0; public: void setType(const RendererCommandType& type) { _type = type; } RendererCommandType getType() const { return _type; } RendererCommandName getName() const { return _name; } void setAdded(const bool& added) { _added = added; } bool isAdded() const { return _added; } virtual bool isNeeded() const { return true; } bool isEqualNameWith(const RendererCommand* command) { return _name == command->_name; } virtual void setRect(const RectF& rect) {} }; class RendererCommandStack { private: typedef pair StubCommand; stack _commands; public: void processCommand(const RendererCommand::RendererCommandName& name , const RendererCommand::RendererCommandType& type) { if (name == RendererCommand::COMMON) return; if (type == RendererCommand::BEGIN) _commands.push(StubCommand(name, type)); else { assert(!_commands.empty()); StubCommand command = _commands.top(); assert(command.first == name); assert(command.second == RendererCommand::BEGIN); _commands.pop(); } } public: static void sendCommand(const CArray>& commands) { for (int i = 0; i < (int) commands.GetCount(); ++i) sendCommand(commands[i]); } static void sendCommand(const SharedPtr& command) { static RendererCommandStack stack; stack.processCommand(command->getName(), command->getType()); } static void sendCommand(const RendererCommand* command) { static RendererCommandStack stack; stack.processCommand(command->getName(), command->getType()); } }; class RendererCommandSender { private: CArray> _commands; protected: ~RendererCommandSender() { _commands.RemoveAll(); } public: void setRendererCommands(const CArray>& commands) { _commands.Append(commands); SEND_TO_STACK(commands); } void addRendererCommand(const SharedPtr& command) { _commands.Add(command); SEND_TO_STACK(command); } protected: void sendRendererCommands(IAVSRenderer* renderer , const RendererCommand::RendererCommandType& type) { if (isRendererCommandExist()) { IAVSRenderer2* renderer2 = getRenderer2(renderer); if (renderer2 != NULL) for (int i = 0; i < (int) _commands.GetCount(); ++i) if (_commands[i]->getType() == type) _commands[i]->send(renderer2); RELEASEINTERFACE(renderer2); } } private: bool isRendererCommandExist() const { return _commands.GetCount() != 0; } IAVSRenderer2* getRenderer2(IAVSRenderer* renderer) const { IAVSRenderer2* renderer2 = NULL; if (!SUCCEEDED(renderer->QueryInterface(__UUIDOF__IAVSRENDERER2, (void**)&renderer2))) renderer2 = NULL; return renderer2; } }; typedef SharedPtr RCommand; class PageBreakRendererCommand : public RendererCommand { public: virtual void send(IAVSRenderer2* renderer) { renderer->CommandLong(c_nPageBreak); } }; class TableStartRendererCommand : public RendererCommand { private: CString _xml; float _top; public: TableStartRendererCommand(const CString& xml) : RendererCommand(TABLE, BEGIN) , _xml(xml) { } public: virtual void send(IAVSRenderer2* renderer) { IAVSRenderer* pRend = NULL; renderer->QueryInterface(__uuidof(IAVSRenderer), (void**)&pRend); pRend->BeginCommand(c_nTable); RELEASEINTERFACE(pRend); BSTR bstrXml = _xml.AllocSysString(); renderer->CommandString2(c_nTableXml, bstrXml); renderer->CommandDouble2(c_nTableTop, _top); SysFreeString(bstrXml); } public: virtual void setRect(const RectF& rect) { _top = rect.Y * 25.4f / 72; } }; class TableEndRendererCommand : public RendererCommand { public: TableEndRendererCommand() : RendererCommand(TABLE, END) { } public: virtual void send(IAVSRenderer2* renderer) { IAVSRenderer* pRend = NULL; renderer->QueryInterface(__uuidof(IAVSRenderer), (void**)&pRend); pRend->EndCommand(c_nTable); RELEASEINTERFACE(pRend); } }; class HeaderStartRendererCommand : public RendererCommand { public: HeaderStartRendererCommand() : RendererCommand(HEADER, BEGIN) { } public: virtual void send(IAVSRenderer2* renderer) { IAVSRenderer* pRend = NULL; renderer->QueryInterface(__uuidof(IAVSRenderer), (void**)&pRend); pRend->BeginCommand(c_nHeader); RELEASEINTERFACE(pRend); SEND_TO_STACK(this); } }; class HeaderEndRendererCommand : public RendererCommand { public: HeaderEndRendererCommand() : RendererCommand(HEADER, END) { } public: virtual void send(IAVSRenderer2* renderer) { IAVSRenderer* pRend = NULL; renderer->QueryInterface(__uuidof(IAVSRenderer), (void**)&pRend); pRend->EndCommand(c_nHeader); RELEASEINTERFACE(pRend); SEND_TO_STACK(this); } }; class BlockStartRendererCommand : public RendererCommand { private: int _headingLevel; int _numberingLevel; int _align; public: BlockStartRendererCommand(const int& headingLevel, const int& numberingLevel , const int& align) : RendererCommand(BLOCK, BEGIN) , _headingLevel(headingLevel), _numberingLevel(numberingLevel) , _align(align) { } public: virtual void send(IAVSRenderer2* renderer2) { if (isNeeded()) { IAVSRenderer* renderer = NULL; renderer2->QueryInterface(__uuidof(IAVSRenderer), (void**)&renderer); renderer->BeginCommand(c_nBlock); if (_headingLevel > 0) renderer2->CommandLong2(c_nBlockHeadingLevel, _headingLevel); if (_numberingLevel > 0) renderer2->CommandLong2(c_nBlockNumberingLevel, _numberingLevel); renderer2->CommandLong2(c_nBlockHorzAlign, _align); SEND_TO_STACK(this); } } public: bool isNeeded() const { return true; } friend class BlockEndRendererCommand; }; class BlockEndRendererCommand : public RendererCommand { private: RCommand _beginBlockCommand; public: BlockEndRendererCommand(const RCommand& beginBlockCommand) : RendererCommand(BLOCK, END) , _beginBlockCommand(beginBlockCommand) { } public: virtual void send(IAVSRenderer2* renderer2) { if (_beginBlockCommand->isNeeded()) { IAVSRenderer* renderer = NULL; renderer2->QueryInterface(__uuidof(IAVSRenderer), (void**)&renderer); renderer->EndCommand(c_nBlock); SEND_TO_STACK(this); } } }; class ColumnCountRendererCommand : public RendererCommand { private: int _columnCount; public: ColumnCountRendererCommand(const int& columnCount) : _columnCount(columnCount) { } public: virtual void send(IAVSRenderer2* renderer2) { renderer2->CommandLong2(c_nColumnCount, _columnCount); } };