ZLTextWordCursor ZLTextAreaController::buildInfos(const ZLTextWordCursor &start) {
	myArea.myLineInfos.clear();

	ZLTextWordCursor cursor = start;
	int textHeight = myArea.height();
	int counter = 0;
	do {
		ZLTextWordCursor paragraphEnd = cursor;
		paragraphEnd.moveToParagraphEnd();
		ZLTextWordCursor paragraphStart = cursor;
		paragraphStart.moveToParagraphStart();

		ZLTextArea::Style style(myArea, myArea.myProperties.baseStyle());
		style.applyControls(paragraphStart, cursor);
		ZLTextLineInfoPtr info = new ZLTextLineInfo(cursor, style.textStyle(), style.bidiLevel());

		while (!info->End.isEndOfParagraph()) {
			info = myArea.processTextLine(style, info->End, paragraphEnd);
			textHeight -= info->Height + info->Descent;
			if ((textHeight < 0) && (counter > 0)) {
				break;
			}
			textHeight -= info->VSpaceAfter;
			cursor = info->End;
			myArea.myLineInfos.push_back(info);
			if (textHeight < 0) {
				break;
			}
			++counter;
		}
	} while (cursor.isEndOfParagraph() && cursor.nextParagraph() && !cursor.paragraphCursor().isEndOfSection() && (textHeight >= 0));

	return cursor;
}
Esempio n. 2
0
bool BookTextView::getHyperlinkInfo(const ZLTextElementRectangle &rectangle, std::string &id, ZLHyperlinkType &type) const {
	if ((rectangle.Kind != ZLTextElement::WORD_ELEMENT) &&
			(rectangle.Kind != ZLTextElement::IMAGE_ELEMENT)) {
		return false;
	}
	ZLTextWordCursor cursor = textArea().startCursor();
	cursor.moveToParagraph(rectangle.ParagraphIndex);
	cursor.moveToParagraphStart();
	ZLTextKind hyperlinkKind = REGULAR;
	for (int i = 0; i < rectangle.ElementIndex; ++i) {
		const ZLTextElement &element = cursor.element();
		if (element.kind() == ZLTextElement::CONTROL_ELEMENT) {
			const ZLTextControlEntry &control = ((const ZLTextControlElement&)element).entry();
			if (control.isHyperlink()) {
				hyperlinkKind = control.kind();
				id = ((const ZLTextHyperlinkControlEntry&)control).label();
				type = ((const ZLTextHyperlinkControlEntry&)control).hyperlinkType();
			} else if (!control.isStart() && (control.kind() == hyperlinkKind)) {
				hyperlinkKind = REGULAR;
			}
		}
		cursor.nextWord();
	}

	return hyperlinkKind != REGULAR;
}
Esempio n. 3
0
bool ZLTextArea::_getHyperlinkInfo(const ZLTextElementRectangle &rectangle, std::string &id, std::string &type, ZLTextKind& hyperlinkKind, int& x1, int&y1, int& x2, int& y2) const {
	if ((rectangle.Kind != ZLTextElement::WORD_ELEMENT) &&
			(rectangle.Kind != ZLTextElement::IMAGE_ELEMENT)) {
		return false;
	}
	ZLTextWordCursor cursor = startCursor();
	cursor.moveToParagraph(rectangle.ParagraphIndex);
	cursor.moveToParagraphStart();
	hyperlinkKind = REGULAR;
	for (int i = 0; i < rectangle.ElementIndex; ++i) {
		const ZLTextElement &element = cursor.element();
		if (element.kind() == ZLTextElement::CONTROL_ELEMENT) {
			const ZLTextControlEntry &control = ((const ZLTextControlElement&)element).entry();
			if (control.isHyperlink()) {
				hyperlinkKind = control.kind();
				id = ((const ZLTextHyperlinkControlEntry&)control).label();
				type = ((const ZLTextHyperlinkControlEntry&)control).hyperlinkType();
				x1 = rectangle.XStart;
				y1 = rectangle.YStart;
				x2 = rectangle.XEnd;
				y2 = rectangle.YEnd;
			} else if (!control.isStart() && (control.kind() == hyperlinkKind)) {
				hyperlinkKind = REGULAR;
			}
		}
		cursor.nextWord();
	}

	return hyperlinkKind != REGULAR;
}
ZLTextWordCursor ZLTextAreaController::findStart(const ZLTextWordCursor &end, SizeUnit unit, int size) {
	ZLTextWordCursor start = end;
	size -= paragraphHeight(start, true, unit);
	bool positionChanged = !start.isStartOfParagraph();
	start.moveToParagraphStart();
	while (size > 0) {
		if (positionChanged && start.paragraphCursor().isEndOfSection()) {
			break;
		}
		if (!start.previousParagraph()) {
			break;
		}
		if (!start.paragraphCursor().isEndOfSection()) {
			positionChanged = true;
		}
		size -= paragraphHeight(start, false, unit);
	}
	skip(start, unit, -size);

	if (unit != LINE_UNIT) {
		bool sameStart = start == end;
		if (!sameStart && start.isEndOfParagraph() && end.isStartOfParagraph()) {
			ZLTextWordCursor startCopy = start;
			startCopy.nextParagraph();
			sameStart = startCopy == end;
		}
		if (sameStart) {
			start = findStart(end, LINE_UNIT, 1);
		}
	}

	return start;
}
Esempio n. 5
0
bool BookTextView::getHyperlinkId(const ZLTextElementArea &area, std::string &id, bool &isExternal) const {
	if ((area.Kind != ZLTextElement::WORD_ELEMENT) &&
			(area.Kind != ZLTextElement::IMAGE_ELEMENT)) {
		return false;
	}
	ZLTextWordCursor cursor = startCursor();
	cursor.moveToParagraph(area.ParagraphNumber);
	cursor.moveToParagraphStart();
	ZLTextKind hyperlinkKind = REGULAR;
	for (int i = 0; i < area.TextElementNumber; ++i) {
		const ZLTextElement &element = cursor.element();
		if (element.kind() == ZLTextElement::CONTROL_ELEMENT) {
			const ZLTextControlEntry &control = ((const ZLTextControlElement&)element).entry();
			if (control.isHyperlink()) {
				hyperlinkKind = control.kind();
				id = ((const ZLTextHyperlinkControlEntry&)control).label();
			} else if (!control.isStart() && (control.kind() == hyperlinkKind)) {
				hyperlinkKind = REGULAR;
			}
		}
		cursor.nextWord();
	}

	isExternal = hyperlinkKind == EXTERNAL_HYPERLINK;
	return hyperlinkKind != REGULAR;
}
void ZLTextAreaController::skip(ZLTextWordCursor &cursor, SizeUnit unit, int size) {
	ZLTextWordCursor paragraphStart = cursor;
	paragraphStart.moveToParagraphStart();
	ZLTextWordCursor paragraphEnd = cursor;
	paragraphEnd.moveToParagraphEnd();

	ZLTextArea::Style style(myArea, myArea.myProperties.baseStyle());
	style.applyControls(paragraphStart, cursor);

	while (!cursor.isEndOfParagraph() && (size > 0)) {
		const ZLTextLineInfoPtr info = 
			myArea.processTextLine(style, cursor, paragraphEnd);
		cursor = info->End;
		size -= infoHeight(*info, unit);
	}
}
Esempio n. 7
0
std::string BookTextView::getFirstInternalHyperlinkId(int x0, int y0, int x1, int y1) {

    std::string id;
    std::string type;

    const ZLTextElementArea * area = elementByCoordinates(x0, y0);
    const ZLTextElementArea * stop_area = elementByCoordinates(x1, y1);

    if ( !area || ((area->Kind != ZLTextElement::WORD_ELEMENT) &&
                   (area->Kind != ZLTextElement::IMAGE_ELEMENT))) {
        return id;
    }
    ZLTextWordCursor cursor = startCursor();
    cursor.moveToParagraph(area->ParagraphIndex);
    int paragraphs = area->ParagraphIndex;
    int end_paragraphs = stop_area ? stop_area->ParagraphIndex : 0;

    do
    {
        cursor.moveToParagraphStart();
        ZLTextKind hyperlinkKind = REGULAR;
        for ( ; !cursor.isEndOfParagraph();) {
            const ZLTextElement &element = cursor.element();
            if (element.kind() == ZLTextElement::CONTROL_ELEMENT) {
                const ZLTextControlEntry &control = ((const ZLTextControlElement&)element).entry();
                if (control.isHyperlink()) {
                    hyperlinkKind = control.kind();
                    id = ((const ZLTextHyperlinkControlEntry&)control).label();
                    type = ((const ZLTextHyperlinkControlEntry&)control).hyperlinkType();
                    if (type == "internal")
                    {
                        return id;
                    }
                } else if (!control.isStart() && (control.kind() == hyperlinkKind)) {
                    hyperlinkKind = REGULAR;
                }
            }
            cursor.nextWord();
        }

    } while( ++paragraphs <= end_paragraphs &&  cursor.nextParagraph());

    return std::string();
}
int ZLTextAreaController::paragraphHeight(const ZLTextWordCursor &cursor, bool beforeCurrentPosition, SizeUnit unit) {
	ZLTextWordCursor word = cursor;
	word.moveToParagraphStart();
	ZLTextWordCursor end = cursor;
	if (!beforeCurrentPosition) {
		end.moveToParagraphEnd();
	}
	
	int size = 0;

	ZLTextArea::Style style(myArea, myArea.myProperties.baseStyle());
	while (!word.equalElementIndex(end)) {
		const ZLTextLineInfoPtr info = myArea.processTextLine(style, word, end);
		word = info->End;
		size += infoHeight(*info, unit);
	}

	return size;
}
const std::vector<ZLTextSelectionModel::Range> &ZLTextSelectionModel::ranges() const {
	if (!myRangeVectorIsUpToDate && !isEmpty()) {
		Range r = internalRange();

		ZLTextWordCursor cursor = myArea.startCursor();
		cursor.moveToParagraph(r.first.ParagraphIndex);
		cursor.moveToParagraphStart();
		int startLevel = 0;
		for (int i = r.first.ElementIndex; i > 0; --i) {
			switch (cursor.element().kind()) {
				case ZLTextElement::START_REVERSED_SEQUENCE_ELEMENT:
					++startLevel;
					break;
				case ZLTextElement::END_REVERSED_SEQUENCE_ELEMENT:
					--startLevel;
					break;
				default:
					break;
			}
			cursor.nextWord();
		}

		cursor.moveToParagraph(r.second.ParagraphIndex);
		cursor.moveToParagraphEnd();
		int endLevel = 0;
		for (int i = cursor.elementIndex() - r.second.ElementIndex; i > 0; --i) {
			cursor.previousWord();
			switch (cursor.element().kind()) {
				case ZLTextElement::START_REVERSED_SEQUENCE_ELEMENT:
					--endLevel;
					break;
				case ZLTextElement::END_REVERSED_SEQUENCE_ELEMENT:
					++endLevel;
					break;
				default:
					break;
			}
		}

		if ((startLevel == 0) && (endLevel == 0)) {
			myRanges.push_back(r);
		} else if (r.first.ParagraphIndex == r.second.ParagraphIndex) {
			BoundElement leftBound = r.first;
			BoundElement rightBound;
			rightBound.Exists = true;
			rightBound.ParagraphIndex = leftBound.ParagraphIndex;
			rightBound.CharIndex = 0;
			cursor.moveTo(r.first.ElementIndex, 0);
			for (int i = r.first.ElementIndex; i < r.second.ElementIndex; ++i) {
				ZLTextElement::Kind kind = cursor.element().kind();
				if ((kind == ZLTextElement::START_REVERSED_SEQUENCE_ELEMENT) ||
						(kind == ZLTextElement::END_REVERSED_SEQUENCE_ELEMENT)) {
					rightBound.ElementIndex = i;
					myRanges.push_back(Range(leftBound, rightBound));
					leftBound = rightBound;
				}
				cursor.nextWord();
			}
			myRanges.push_back(Range(leftBound, r.second));
		} else {
			BoundElement leftBound = r.first;
			if (startLevel > 0) {
				BoundElement rightBound;
				rightBound.Exists = true;
				rightBound.ParagraphIndex = leftBound.ParagraphIndex;
				rightBound.ElementIndex = leftBound.ElementIndex;
				rightBound.CharIndex = 0;
				cursor.moveToParagraph(r.first.ParagraphIndex);
				cursor.moveTo(r.first.ElementIndex, 0);
				while (startLevel > 0) {
					switch(cursor.element().kind()) {
						case ZLTextElement::START_REVERSED_SEQUENCE_ELEMENT:
							++startLevel;
							rightBound.ElementIndex = cursor.elementIndex();
							myRanges.push_back(Range(leftBound, rightBound));
							leftBound = rightBound;
							break;
						case ZLTextElement::END_REVERSED_SEQUENCE_ELEMENT:
							--startLevel;
							rightBound.ElementIndex = cursor.elementIndex();
							myRanges.push_back(Range(leftBound, rightBound));
							leftBound = rightBound;
							break;
						default:
							break;
					}
					cursor.nextWord();
				}
			}

			BoundElement rightBound1 = r.second;
			if (endLevel > 0) {
				BoundElement leftBound1;
				leftBound1.Exists = true;
				leftBound1.ParagraphIndex = rightBound1.ParagraphIndex;
				leftBound1.ElementIndex = rightBound1.ElementIndex;
				leftBound1.CharIndex = 0;
				cursor.moveToParagraph(r.second.ParagraphIndex);
				cursor.moveTo(r.second.ElementIndex, 0);
				while (endLevel > 0) {
					switch(cursor.element().kind()) {
						case ZLTextElement::START_REVERSED_SEQUENCE_ELEMENT:
							--endLevel;
							leftBound1.ElementIndex = cursor.elementIndex();
							myRanges.push_back(Range(leftBound1, rightBound1));
							rightBound1 = leftBound1;
							break;
						case ZLTextElement::END_REVERSED_SEQUENCE_ELEMENT:
							++endLevel;
							rightBound1.ElementIndex = cursor.elementIndex();
							myRanges.push_back(Range(leftBound1, rightBound1));
							rightBound1 = leftBound1;
							break;
						default:
							break;
					}
					cursor.previousWord();
				}
			}
			myRanges.push_back(Range(leftBound, rightBound1));
		}

		myRangeVectorIsUpToDate = true;
	}
	return myRanges;
}