Files
core/ASCImageStudio3/ASCGraphics/Interfaces/TextMeasurer/RendererCommands.h

315 lines
7.6 KiB
C++

#pragma once
#include <utility>
#include <stack>
#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<RendererCommand::RendererCommandName
, RendererCommand::RendererCommandType> StubCommand;
stack<StubCommand> _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<SharedPtr<RendererCommand>>& commands) {
for (int i = 0; i < (int) commands.GetCount(); ++i)
sendCommand(commands[i]);
}
static void sendCommand(const SharedPtr<RendererCommand>& 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<SharedPtr<RendererCommand>> _commands;
protected:
~RendererCommandSender() {
_commands.RemoveAll();
}
public:
void setRendererCommands(const CArray<SharedPtr<RendererCommand>>& commands) {
_commands.Append(commands);
SEND_TO_STACK(commands);
}
void addRendererCommand(const SharedPtr<RendererCommand>& 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<RendererCommand> 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);
}
};