QtNovelUI/libTextEdit/text_present.cpp

315 lines
9.1 KiB
C++

#include "text_present.h"
#include <tuple>
using namespace std;
using namespace model_text;
CharStream CharSetU16::combineToU(const QString &buffer) {
QList<uint32_t> retvs;
if (buffer.size() == 0)
return retvs;
tuple<uint32_t, int> combine_current;
auto aval = buffer[0];
if (buffer.size() < 2)
combine_current = std::make_tuple(aval.unicode(), 1);
else if (buffer.size() >= 2) {
auto bval = buffer[1];
if (aval.isHighSurrogate() && bval.isLowSurrogate()) {
uint32_t avalx = aval.unicode();
combine_current = std::make_tuple((avalx << 16) + bval.unicode(), 2);
} else {
combine_current = std::make_tuple(aval.unicode(), 1);
}
}
retvs.append(std::get<0>(combine_current));
retvs.append(combineToU(buffer.mid(std::get<1>(combine_current))));
return retvs;
}
QString CharSetU16::splitToC(const CharStream &buffer) {
if (!buffer.size())
return "";
QString acc_str = "";
auto head = buffer[0];
if (head > 0xffffu) {
auto high_v = (head & 0xffff0000u) >> 16;
auto low_v = head & 0xffffu;
auto hc = QChar((ushort)high_v);
auto lc = QChar((ushort)low_v);
acc_str.append(hc);
acc_str.append(lc);
} else {
acc_str.append(QChar((ushort)head & 0xffffu));
}
acc_str.append(splitToC(buffer.mid(1)));
return acc_str;
}
bool CharSetU16::contains(uint32_t code) {
if (code <= 0xffffu)
return true;
else {
auto high_v = (code & 0xffff0000u) >> 16;
auto low_v = code & 0xffffu;
auto hc = QChar((ushort)high_v);
auto lc = QChar((ushort)low_v);
return hc.isHighSurrogate() && lc.isLowSurrogate();
}
}
uint CharSetU16::size() { return 1114111u; }
void WsDocument::bindFormat(std::shared_ptr<DocFormat> f) { this->document_format = f; }
std::shared_ptr<DocFormat> WsDocument::getFormat() const { return this->document_format; }
uint32_t WsDocument::blockCount() const
{
return this->block_store.size();
}
QList<std::shared_ptr<WsBlock> > WsDocument::getBlocks(uint32_t offset, uint32_t count) const
{
QList<std::shared_ptr<WsBlock>> retvs;
for (auto idx = offset; idx < this->block_store.size(); ++idx)
retvs << this->block_store.at(idx);
return retvs;
}
void WsDocument::delBlocks(uint32_t offset, uint32_t count)
{
for(auto idx=offset; idx<this->block_store.size();){
this->block_store.removeAt(idx);
}
}
void WsDocument::addBlocks(const QList<std::shared_ptr<WsBlock>> &blks, uint32_t offset)
{
if(offset < this->block_store.size()){
for(auto ptr : blks)
this->block_store.insert(offset, ptr);
}
else{
this->block_store.append(blks);
}
}
QString WsDocument::toPlainText() const
{
QString text_content;
for(auto idx=0; idx<blockCount(); ++idx){
text_content += getBlocks(idx).at(0)->toText();
}
return text_content;
}
void WsDocument::setPlainText(const QString &text)
{
auto sections = text.split("\n");
QList<std::shared_ptr<WsBlock>> blocks;
for(auto &t : sections){
auto binst = std::make_shared<WsBlock>();
blocks.append(binst);
// 转换文本为内存实例
auto codes = CharSetU16::combineToU(t);
auto chars = WsChar::convertFrom(codes);
// 填充段落实例
QList<Element*> buffers;
for(auto &ptr : chars){
ptr->bindFormat(this->getFormat()->defaultCharFormat());
ptr->refer(binst);
buffers.append(ptr);
}
binst->addElements(buffers);
}
addBlocks(blocks);
}
void WsBlock::addElements(const QList<Element*> &text, uint32_t offset){
if(offset < this->element_store.size()){
for(auto *ptr : text)
this->element_store.insert(offset, ptr);
}
else{
this->element_store.append(text);
}
}
QList<Element *> WsBlock::getElements(uint32_t offset, uint32_t count) const
{
QList<Element*> retvs;
for (auto idx = offset; idx < this->element_store.size(); ++idx)
retvs << this->element_store.at(idx);
return retvs;
}
void WsBlock::delElements(uint32_t offset, uint32_t count)
{
for(auto idx=offset; idx<this->element_store.size();){
delete element_store.at(idx);
this->element_store.removeAt(idx);
}
}
QString WsBlock::toText() const
{
QString text_content;
for(auto &it : element_store)
text_content += it->toText();
return text_content;
}
DocFormat::DocFormat(){}
DocFormat::DocFormat(const DocFormat &other){
this->char_format = other.char_format;
this->line_height = other.line_height;
this-> indent_char_count = other.indent_char_count;
this-> margins_store = other.margins_store;
this-> visible_of_additional = other.visible_of_additional;
}
double DocFormat::lineHeight() const { return line_height; }
QMargins DocFormat::margins() const { return margins_store; }
double DocFormat::indentChars() const { return indent_char_count; }
bool DocFormat::additionalVisible() const { return visible_of_additional; }
std::shared_ptr<CharFormat> DocFormat::defaultCharFormat() const { return this->char_format; }
void DocFormat::setLineHeight(double val) { this->line_height = val; }
void DocFormat::setMargins(const QMargins &val) { this->margins_store = val; }
void DocFormat::setIndentChars(double n) { this->indent_char_count = n; }
void DocFormat::setAdditionalVisible(bool ste) { this->visible_of_additional = ste; }
void DocFormat::setDefaultCharFormat(std::shared_ptr<CharFormat> format) { this->char_format = format; }
DocFormat &DocFormat::operator=(const DocFormat &other){
this->char_format = other.char_format;
this->line_height = other.line_height;
this-> indent_char_count = other.indent_char_count;
this-> margins_store = other.margins_store;
this-> visible_of_additional = other.visible_of_additional;
return *this;
}
CharFormat::CharFormat(qulonglong format_id){
this->unique_id = format_id;
}
CharFormat::CharFormat(const CharFormat &other){
this->unique_id = other.unique_id;
this->point_size = other.point_size;
this->fontfamily_store = other.fontfamily_store;
this->bold_store = other.bold_store;
this->italic_flag = other.italic_flag;
this->kerning_flag = other.kerning_flag;
this->overline_flag = other.overline_flag;
this->underline_flag = other.underline_flag;
this->float_Height = other.float_Height;
this->weight_store = other.weight_store;
}
qulonglong CharFormat::formatID() const { return unique_id; }
uint32_t CharFormat::pointSize() const { return point_size; }
QString CharFormat::fontFamily() const { return fontfamily_store; }
bool CharFormat::bold() const { return bold_store; }
bool CharFormat::italic() const { return italic_flag; }
bool CharFormat::kerning() const { return kerning_flag; }
bool CharFormat::overline() const { return overline_flag; }
bool CharFormat::underline() const { return underline_flag; }
double CharFormat::floatHeight() const { return float_Height; }
QFont::Weight CharFormat::weight() const { return weight_store; }
void CharFormat::setPointSize(uint32_t val){this->point_size = val;}
void CharFormat::setFontFamily(const QString &name){this->fontfamily_store = name;}
void CharFormat::setBold(bool ste){this->bold_store = ste;}
void CharFormat::setItalic(bool ste){this->italic_flag = ste;}
void CharFormat::setKerning(bool ste){this->kerning_flag = ste;}
void CharFormat::setOverline(bool ste){this->overline_flag = ste;}
void CharFormat::setUnderline(bool ste){this->underline_flag = ste;}
void CharFormat::setFloatHeight(double val){this->float_Height = val;}
void CharFormat::setWeight(QFont::Weight val){this->weight_store = val;}
bool CharFormat::operator==(const CharFormat &other){
return this->point_size == other.point_size &&
this->fontfamily_store == other.fontfamily_store &&
this->bold_store == other.bold_store &&
this->italic_flag == other.italic_flag &&
this->kerning_flag == other.kerning_flag &&
this->overline_flag == other.overline_flag &&
this->underline_flag == other.underline_flag &&
this->float_Height == other.float_Height &&
this->weight_store == other.weight_store;
}
CharFormat &CharFormat::operator=(const CharFormat &other) {
this->point_size = other.point_size;
this->fontfamily_store = other.fontfamily_store;
this->bold_store = other.bold_store;
this->italic_flag = other.italic_flag;
this->kerning_flag = other.kerning_flag;
this->overline_flag = other.overline_flag;
this->underline_flag = other.underline_flag;
this->float_Height = other.float_Height;
this->weight_store = other.weight_store;
return *this;
}
QList<WsChar *> WsChar::convertFrom(const CharStream &codes)
{
QList<WsChar*> buffers;
for(auto &c : codes)
buffers << new WsChar(c);
return buffers;
}
uint32_t WsChar::blockIndex() const
{
return blockRefer()->blockIndex();
}
void WsPart::insertChars(const QList<WsChar *> &text, uint32_t offset)
{
}