bool
ParagraphLayout::_AppendGlyphInfos(const TextSpan& span)
{
	int charCount = span.CountChars();
	if (charCount == 0)
		return true;

	const BString& text = span.Text();
	const BFont& font = span.Style().Font();

	// Allocate arrays
	float* escapementArray = new (std::nothrow) float[charCount];
	if (escapementArray == NULL)
		return false;
	ArrayDeleter<float> escapementDeleter(escapementArray);

	// Fetch glyph spacing information
	font.GetEscapements(text, charCount, escapementArray);

	// Append to glyph buffer and convert escapement scale
	float size = font.Size();
	const char* c = text.String();
	for (int i = 0; i < charCount; i++) {
		if (!_AppendGlyphInfo(UTF8ToCharCode(&c), escapementArray[i] * size,
				span.Style())) {
			return false;
		}
	}

	return true;
}
Exemple #2
0
bool
Paragraph::Insert(int32 offset, const TextSpan& newSpan)
{
	_InvalidateCachedLength();

	int32 index = 0;
	while (index < fTextSpans.CountItems()) {
		const TextSpan& span = fTextSpans.ItemAtFast(index);
		if (offset - span.CountChars() < 0)
			break;
		offset -= span.CountChars();
		index++;
	}

	if (fTextSpans.CountItems() == index)
		return Append(newSpan);

	// Try to merge with span at index if the TextStyles are equal
	TextSpan span = fTextSpans.ItemAtFast(index);
	if (span.Style() == newSpan.Style()) {
		span.Insert(offset, newSpan.Text());
		return fTextSpans.Replace(index, span);
	}

	if (offset == 0) {
		if (index > 0) {
			// Try to merge with TextSpan before if offset == 0 && index > 0
			TextSpan span = fTextSpans.ItemAtFast(index - 1);
			if (span.Style() == newSpan.Style()) {
				span.Insert(span.CountChars(), newSpan.Text());
				return fTextSpans.Replace(index - 1, span);
			}
		}
		// Just insert the new span before the one at index
		return fTextSpans.Add(newSpan, index);
	}

	// Split the span,
	TextSpan spanBefore = span.SubSpan(0, offset);
	TextSpan spanAfter = span.SubSpan(offset, span.CountChars() - offset);

	return fTextSpans.Replace(index, spanBefore)
		&& fTextSpans.Add(newSpan, index + 1)
		&& fTextSpans.Add(spanAfter, index + 2);
}