mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 10:59:17 +08:00
315 lines
7.6 KiB
C++
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);
|
|
}
|
|
}; |