mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 08:47:28 +01:00
151 lines
4.9 KiB
C++
151 lines
4.9 KiB
C++
|
|
#include "word_wrap_view.h"
|
|
#include "utility.h"
|
|
|
|
namespace Reader
|
|
{
|
|
|
|
void WordWrapTextView::nextPage() {
|
|
if(m_nextPageOffset >= m_length) {
|
|
return;
|
|
}
|
|
m_pageOffset = m_nextPageOffset;
|
|
markRectAsDirty(bounds());
|
|
}
|
|
|
|
void WordWrapTextView::setText(const char* text, int length) {
|
|
PointerTextView::setText(text);
|
|
m_length = length;
|
|
}
|
|
|
|
void WordWrapTextView::previousPage() {
|
|
if(m_pageOffset <= 0) {
|
|
return;
|
|
}
|
|
|
|
const int charWidth = m_font->glyphSize().width();
|
|
const int charHeight = m_font->glyphSize().height();
|
|
|
|
const char * endOfWord = text() + m_pageOffset - 1;
|
|
const char * startOfWord = UTF8Helper::BeginningOfWord(text(), endOfWord);
|
|
|
|
KDPoint textEndPosition(m_frame.width() - k_margin, m_frame.height() - k_margin);
|
|
|
|
while(startOfWord>=text()) {
|
|
startOfWord = UTF8Helper::BeginningOfWord(text(), endOfWord);
|
|
endOfWord = UTF8Helper::EndOfWord(startOfWord);
|
|
KDSize textSize = m_font->stringSizeUntil(startOfWord, endOfWord);
|
|
KDPoint textStartPosition = KDPoint(textEndPosition.x()-textSize.width(), textEndPosition.y());
|
|
|
|
if(textStartPosition.x() < k_margin) {
|
|
textEndPosition = KDPoint(m_frame.width() - k_margin, textEndPosition.y() - charHeight);
|
|
textStartPosition = KDPoint(textEndPosition.x() - textSize.width(), textEndPosition.y());
|
|
}
|
|
if(textEndPosition.y() - textSize.height() < k_margin) {
|
|
break;
|
|
}
|
|
|
|
--startOfWord;
|
|
while(startOfWord >= text() && (*startOfWord == ' ' || *startOfWord == '\n')) {
|
|
if(*startOfWord == ' ') {
|
|
textStartPosition = KDPoint(textStartPosition.x() - charWidth, textStartPosition.y());
|
|
}
|
|
else {
|
|
textStartPosition = KDPoint(m_frame.width() - k_margin, textStartPosition.y() - charHeight);
|
|
}
|
|
--startOfWord;
|
|
}
|
|
|
|
if(textStartPosition.y() < k_margin) { // If out of page, quit
|
|
break;
|
|
}
|
|
|
|
if(textStartPosition.y() != textEndPosition.y()) { // If line changed, x is at start of line
|
|
textStartPosition = KDPoint(m_frame.width() - k_margin, textStartPosition.y());
|
|
}
|
|
if(textStartPosition.x() < k_margin) { // Go to line if left overflow
|
|
textStartPosition = KDPoint(m_frame.width() - k_margin, textStartPosition.y() - charHeight);
|
|
}
|
|
|
|
textEndPosition = textStartPosition;
|
|
endOfWord = startOfWord + 1;
|
|
}
|
|
if(startOfWord + 1 == text()) {
|
|
m_pageOffset = 0;
|
|
}
|
|
else {
|
|
m_pageOffset = UTF8Helper::EndOfWord(startOfWord) - text() + 1;
|
|
}
|
|
markRectAsDirty(bounds());
|
|
}
|
|
|
|
void WordWrapTextView::drawRect(KDContext * ctx, KDRect rect) const {
|
|
ctx->fillRect(KDRect(0, 0, bounds().width(), bounds().height()), m_backgroundColor);
|
|
|
|
const char * endOfFile = text() + m_length;
|
|
const char * startOfWord = text() + m_pageOffset;
|
|
const char * endOfWord = UTF8Helper::EndOfWord(startOfWord);
|
|
KDPoint textPosition(k_margin, k_margin);
|
|
|
|
const int wordMaxLength = 128;
|
|
char word[wordMaxLength];
|
|
|
|
const int charWidth = m_font->glyphSize().width();
|
|
const int charHeight = m_font->glyphSize().height();
|
|
|
|
while(startOfWord < endOfFile) {
|
|
KDSize textSize = m_font->stringSizeUntil(startOfWord, endOfWord);
|
|
KDPoint nextTextPosition = KDPoint(textPosition.x()+textSize.width(), textPosition.y());
|
|
|
|
if(nextTextPosition.x() > m_frame.width() - k_margin) { // Right overflow
|
|
textPosition = KDPoint(k_margin, textPosition.y() + textSize.height());
|
|
nextTextPosition = KDPoint(k_margin + textSize.width(), textPosition.y());
|
|
}
|
|
|
|
if(textPosition.y() + textSize.height() > m_frame.height() - k_margin) { // Bottom overflow
|
|
break;
|
|
}
|
|
|
|
stringNCopy(word, wordMaxLength, startOfWord, endOfWord-startOfWord);
|
|
ctx->drawString(word, textPosition, m_font, m_textColor, m_backgroundColor);
|
|
|
|
while(*endOfWord == ' ' || *endOfWord == '\n') {
|
|
if(*endOfWord == ' ') {
|
|
nextTextPosition = KDPoint(nextTextPosition.x() + charWidth, nextTextPosition.y());
|
|
}
|
|
else {
|
|
nextTextPosition = KDPoint(k_margin, nextTextPosition.y() + charHeight);
|
|
}
|
|
++endOfWord;
|
|
}
|
|
|
|
//We must change value of startOfWord now to avoid having
|
|
//two times the same word if the break below is used
|
|
startOfWord = endOfWord;
|
|
|
|
if(nextTextPosition.y() + textSize.height() > m_frame.height() - k_margin) { // If out of page, quit
|
|
break;
|
|
}
|
|
if(nextTextPosition.y() != textPosition.y()) { // If line changed, x is at start of line
|
|
nextTextPosition = KDPoint(k_margin, nextTextPosition.y());
|
|
}
|
|
if(nextTextPosition.x() > m_frame.width() - k_margin) { // Go to line if right overflow
|
|
nextTextPosition = KDPoint(k_margin, nextTextPosition.y() + textSize.height());
|
|
}
|
|
|
|
textPosition = nextTextPosition;
|
|
endOfWord = UTF8Helper::EndOfWord(startOfWord);
|
|
}
|
|
|
|
m_nextPageOffset = startOfWord - text();
|
|
};
|
|
|
|
int WordWrapTextView::getPageOffset() const {
|
|
return m_pageOffset;
|
|
}
|
|
|
|
void WordWrapTextView::setPageOffset(int o) {
|
|
m_pageOffset = o;
|
|
}
|
|
|
|
} |