HaikuDepot: Remove Custom List

Further removal of the use of custom list class;
this time part of the test engine inside HD.

Relates To #15534

Change-Id: Ia1f1d7c2577f92bba96da392fd48949a13b5a169
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3745
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Andrew Lindesay
2021-02-28 11:17:30 +00:00
parent 6c04dd4898
commit 3d2fd2acaf
5 changed files with 161 additions and 112 deletions
+96 -64
View File
@@ -1,5 +1,6 @@
/*
* Copyright 2013-2014, Stephan Aßmus <[email protected]>.
* Copyright 2021, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@@ -63,6 +64,20 @@ Paragraph::operator!=(const Paragraph& other) const
}
int32
Paragraph::CountTextSpans() const
{
return static_cast<int32>(fTextSpans.size());
}
const TextSpan&
Paragraph::TextSpanAtIndex(int32 index) const
{
return fTextSpans[index];
}
void
Paragraph::SetStyle(const ParagraphStyle& style)
{
@@ -76,15 +91,17 @@ Paragraph::Prepend(const TextSpan& span)
_InvalidateCachedLength();
// Try to merge with first span if the TextStyles are equal
if (fTextSpans.CountItems() > 0) {
const TextSpan& firstSpan = fTextSpans.ItemAtFast(0);
if (!fTextSpans.empty()) {
const TextSpan& firstSpan = fTextSpans[0];
if (firstSpan.Style() == span.Style()) {
BString text(span.Text());
text.Append(firstSpan.Text());
return fTextSpans.Replace(0, TextSpan(text, span.Style()));
fTextSpans[0] = TextSpan(text, span.Style());
return true;
}
}
return fTextSpans.Add(span, 0);
fTextSpans.push_back(span);
return true;
}
@@ -94,16 +111,18 @@ Paragraph::Append(const TextSpan& span)
_InvalidateCachedLength();
// Try to merge with last span if the TextStyles are equal
if (fTextSpans.CountItems() > 0) {
const TextSpan& lastSpan = fTextSpans.LastItem();
if (!fTextSpans.empty()) {
const TextSpan& lastSpan = fTextSpans[fTextSpans.size() - 1];
if (lastSpan.Style() == span.Style()) {
BString text(lastSpan.Text());
text.Append(span.Text());
fTextSpans.Remove();
return fTextSpans.Add(TextSpan(text, span.Style()));
fTextSpans.clear();
fTextSpans.push_back(TextSpan(text, span.Style()));
return true;
}
}
return fTextSpans.Add(span);
fTextSpans.push_back(span);
return true;
}
@@ -113,44 +132,52 @@ 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++;
{
int32 countTextSpans = static_cast<int32>(fTextSpans.size());
while (index < countTextSpans) {
const TextSpan& span = fTextSpans[index];
if (offset - span.CountChars() < 0)
break;
offset -= span.CountChars();
index++;
}
if (countTextSpans == index)
return Append(newSpan);
}
if (fTextSpans.CountItems() == index)
return Append(newSpan);
// Try to merge with span at index if the TextStyles are equal
TextSpan span = fTextSpans.ItemAtFast(index);
TextSpan span = fTextSpans[index];
if (span.Style() == newSpan.Style()) {
span.Insert(offset, newSpan.Text());
return fTextSpans.Replace(index, span);
fTextSpans[index] = span;
return true;
}
if (offset == 0) {
if (index > 0) {
// Try to merge with TextSpan before if offset == 0 && index > 0
TextSpan span = fTextSpans.ItemAtFast(index - 1);
TextSpan span = fTextSpans[index - 1];
if (span.Style() == newSpan.Style()) {
span.Insert(span.CountChars(), newSpan.Text());
return fTextSpans.Replace(index - 1, span);
fTextSpans[index - 1] = span;
return true;
}
}
// Just insert the new span before the one at index
return fTextSpans.Add(newSpan, index);
fTextSpans.insert(fTextSpans.begin() + index, newSpan);
return true;
}
// 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);
fTextSpans[index] = spanBefore;
fTextSpans.insert(fTextSpans.begin() + (index + 1), newSpan);
fTextSpans.insert(fTextSpans.begin() + (index + 2), spanAfter);
return true;
}
@@ -163,40 +190,44 @@ Paragraph::Remove(int32 offset, int32 length)
_InvalidateCachedLength();
int32 index = 0;
while (index < fTextSpans.CountItems()) {
const TextSpan& span = fTextSpans.ItemAtFast(index);
if (offset - span.CountChars() < 0)
break;
offset -= span.CountChars();
index++;
{
int32 countTextSpans = static_cast<int32>(fTextSpans.size());
while (index < countTextSpans) {
const TextSpan& span = fTextSpans[index];
if (offset - span.CountChars() < 0)
break;
offset -= span.CountChars();
index++;
}
if (index >= countTextSpans)
return false;
}
if (index >= fTextSpans.CountItems())
return false;
TextSpan span(fTextSpans.ItemAtFast(index));
TextSpan span(fTextSpans[index]);
int32 removeLength = std::min(span.CountChars() - offset, length);
span.Remove(offset, removeLength);
length -= removeLength;
index += 1;
// Remove more spans if necessary
while (length > 0 && index < fTextSpans.CountItems()) {
int32 spanLength = fTextSpans.ItemAtFast(index).CountChars();
while (length > 0 && index < static_cast<int32>(fTextSpans.size())) {
int32 spanLength = fTextSpans[index].CountChars();
if (spanLength <= length) {
fTextSpans.Remove(index);
fTextSpans.erase(fTextSpans.begin() + index);
length -= spanLength;
} else {
// Reached last span
removeLength = std::min(length, spanLength);
TextSpan lastSpan = fTextSpans.ItemAtFast(index).SubSpan(
TextSpan lastSpan = fTextSpans[index].SubSpan(
removeLength, spanLength - removeLength);
// Try to merge with first span, otherwise replace span at index
if (lastSpan.Style() == span.Style()) {
span.Insert(span.CountChars(), lastSpan.Text());
fTextSpans.Remove(index);
fTextSpans.erase(fTextSpans.begin() + index);
} else {
fTextSpans.Replace(index, lastSpan);
fTextSpans[index] = lastSpan;
}
break;
@@ -206,22 +237,22 @@ Paragraph::Remove(int32 offset, int32 length)
// See if anything from the TextSpan at offset remained, keep it as empty
// span if it is the last remaining span.
index--;
if (span.CountChars() > 0 || fTextSpans.CountItems() == 1) {
fTextSpans.Replace(index, span);
if (span.CountChars() > 0 || static_cast<int32>(fTextSpans.size()) == 1) {
fTextSpans[index] = span;
} else {
fTextSpans.Remove(index);
fTextSpans.erase(fTextSpans.begin() + index);
index--;
}
// See if spans can be merged after one has been removed.
if (index >= 0 && index + 1 < fTextSpans.CountItems()) {
const TextSpan& span1 = fTextSpans.ItemAtFast(index);
const TextSpan& span2 = fTextSpans.ItemAtFast(index + 1);
if (index >= 0 && index + 1 < static_cast<int32>(fTextSpans.size())) {
const TextSpan& span1 = fTextSpans[index];
const TextSpan& span2 = fTextSpans[index + 1];
if (span1.Style() == span2.Style()) {
span = span1;
span.Append(span2.Text());
fTextSpans.Replace(index, span);
fTextSpans.Remove(index + 1);
fTextSpans[index] = span;
fTextSpans.erase(fTextSpans.begin() + (index + 1));
}
}
@@ -232,7 +263,7 @@ Paragraph::Remove(int32 offset, int32 length)
void
Paragraph::Clear()
{
fTextSpans.Clear();
fTextSpans.clear();
}
@@ -243,8 +274,9 @@ Paragraph::Length() const
return fCachedLength;
int32 length = 0;
for (int32 i = fTextSpans.CountItems() - 1; i >= 0; i--) {
const TextSpan& span = fTextSpans.ItemAtFast(i);
std::vector<TextSpan>::const_iterator it;
for (it = fTextSpans.begin(); it != fTextSpans.end(); it++) {
const TextSpan& span = *it;
length += span.CountChars();
}
@@ -256,7 +288,7 @@ Paragraph::Length() const
bool
Paragraph::IsEmpty() const
{
return fTextSpans.CountItems() == 0;
return fTextSpans.empty();
}
@@ -275,11 +307,11 @@ BString
Paragraph::Text() const
{
BString result;
int32 count = fTextSpans.CountItems();
for (int32 i = 0; i < count; i++)
result << fTextSpans.ItemAtFast(i).Text();
std::vector<TextSpan>::const_iterator it;
for (it = fTextSpans.begin(); it != fTextSpans.end(); it++) {
const TextSpan& span = *it;
result << span.Text();
}
return result;
}
@@ -303,9 +335,9 @@ Paragraph::SubParagraph(int32 start, int32 length) const
Paragraph result(fStyle);
int32 count = fTextSpans.CountItems();
for (int32 i = 0; i < count; i++) {
const TextSpan& span = fTextSpans.ItemAtFast(i);
std::vector<TextSpan>::const_iterator it;
for (it = fTextSpans.begin(); it != fTextSpans.end(); it++) {
const TextSpan& span = *it;
int32 spanLength = span.CountChars();
if (spanLength == 0)
continue;
@@ -339,14 +371,14 @@ Paragraph::SubParagraph(int32 start, int32 length) const
void
Paragraph::PrintToStream() const
{
int32 spanCount = fTextSpans.CountItems();
int32 spanCount = static_cast<int32>(fTextSpans.size());
if (spanCount == 0) {
printf(" <p/>\n");
return;
}
printf(" <p>\n");
for (int32 i = 0; i < spanCount; i++) {
const TextSpan& span = fTextSpans.ItemAtFast(i);
const TextSpan& span = fTextSpans[i];
if (span.CountChars() == 0)
printf(" <span/>\n");
else {
+7 -7
View File
@@ -1,18 +1,17 @@
/*
* Copyright 2013-2014, Stephan Aßmus <[email protected]>.
* Copyright 2021, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef PARAGRAPH_H
#define PARAGRAPH_H
#include "List.h"
#include <vector>
#include "ParagraphStyle.h"
#include "TextSpan.h"
typedef List<TextSpan, false> TextSpanList;
class Paragraph {
public:
Paragraph();
@@ -27,8 +26,8 @@ public:
inline const ParagraphStyle& Style() const
{ return fStyle; }
inline const TextSpanList& TextSpans() const
{ return fTextSpans; }
int32 CountTextSpans() const;
const TextSpan& TextSpanAtIndex(int32 index) const;
bool Prepend(const TextSpan& span);
bool Append(const TextSpan& span);
@@ -51,7 +50,8 @@ private:
private:
ParagraphStyle fStyle;
TextSpanList fTextSpans;
std::vector<TextSpan>
fTextSpans;
mutable int32 fCachedLength;
};
@@ -8,6 +8,7 @@
* Marc Flerackers, [email protected]
* Hiroshi Lockheimer (BTextView is based on his STEEngine)
* Oliver Tappe, [email protected]
* Andrew Lindesay, [email protected]
*/
#include "ParagraphLayout.h"
@@ -177,7 +178,7 @@ ParagraphLayout::ParagraphLayout()
ParagraphLayout::ParagraphLayout(const Paragraph& paragraph)
:
fTextSpans(paragraph.TextSpans()),
fTextSpans(),
fParagraphStyle(paragraph.Style()),
fWidth(0.0f),
@@ -186,6 +187,7 @@ ParagraphLayout::ParagraphLayout(const Paragraph& paragraph)
fGlyphInfos(),
fLineInfos()
{
_AppendTextSpans(paragraph);
_Init();
}
@@ -212,7 +214,8 @@ ParagraphLayout::~ParagraphLayout()
void
ParagraphLayout::SetParagraph(const Paragraph& paragraph)
{
fTextSpans = paragraph.TextSpans();
fTextSpans.clear();
_AppendTextSpans(paragraph);
fParagraphStyle = paragraph.Style();
_Init();
@@ -484,9 +487,9 @@ ParagraphLayout::_Init()
{
fGlyphInfos.Clear();
int spanCount = fTextSpans.CountItems();
for (int i = 0; i < spanCount; i++) {
const TextSpan& span = fTextSpans.ItemAtFast(i);
std::vector<TextSpan>::const_iterator it;
for (it = fTextSpans.begin(); it != fTextSpans.end(); it++) {
const TextSpan& span = *it;
if (!_AppendGlyphInfos(span)) {
fprintf(stderr, "%p->ParagraphLayout::_Init() - Out of memory\n",
this);
@@ -852,27 +855,27 @@ ParagraphLayout::_FinalizeLine(int lineStart, int lineEnd, int lineIndex,
while (i >= spanEnd) {
spanIndex++;
const TextSpan& span = fTextSpans.ItemAt(spanIndex);
const TextSpan& span = fTextSpans[spanIndex];
spanStart = spanEnd;
spanEnd += span.CountChars();
addSpan = true;
}
if (addSpan) {
const TextSpan& span = fTextSpans.ItemAt(spanIndex);
const TextSpan& span = fTextSpans[spanIndex];
TextSpan subSpan = span.SubSpan(i - spanStart,
(lineEnd - spanStart + 1) - (i - spanStart));
line.layoutedSpans.Add(subSpan);
line.layoutedSpans.push_back(subSpan);
_IncludeStyleInLine(line, span.Style());
}
}
if (fGlyphInfos.CountItems() == 0 && fTextSpans.CountItems() > 0) {
if (fGlyphInfos.CountItems() == 0 && !fTextSpans.empty()) {
// When the layout contains no glyphs, but there is at least one
// TextSpan in the paragraph, use the font info from that span
// to calculate the height of the first LineInfo.
const TextSpan& span = fTextSpans.ItemAtFast(0);
line.layoutedSpans.Add(span);
const TextSpan& span = fTextSpans[0];
line.layoutedSpans.push_back(span);
_IncludeStyleInLine(line, span.Style());
}
@@ -908,9 +911,9 @@ ParagraphLayout::_DrawLine(BView* view, const BPoint& offset,
const LineInfo& line) const
{
int textOffset = line.textOffset;
int spanCount = line.layoutedSpans.CountItems();
int spanCount = static_cast<int>(line.layoutedSpans.size());
for (int i = 0; i < spanCount; i++) {
const TextSpan& span = line.layoutedSpans.ItemAtFast(i);
const TextSpan& span = line.layoutedSpans[i];
_DrawSpan(view, offset, span, textOffset);
textOffset += span.CountChars();
}
@@ -973,3 +976,12 @@ ParagraphLayout::_GetEmptyLayoutBounds(float& x1, float& y1, float& x2,
y1 = lineInfo.y;
y2 = lineInfo.y + lineInfo.height;
}
void
ParagraphLayout::_AppendTextSpans(const Paragraph& paragraph)
{
int32 countTextSpans = paragraph.CountTextSpans();
for (int32 i = 0; i< countTextSpans; i++)
fTextSpans.push_back(paragraph.TextSpanAtIndex(i));
}
+11 -3
View File
@@ -1,16 +1,20 @@
/*
* Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef PARAGRAPH_LAYOUT_H
#define PARAGRAPH_LAYOUT_H
#include <vector>
#include <Font.h>
#include <Referenceable.h>
#include <String.h>
#include "Paragraph.h"
#include "CharacterStyle.h"
#include "List.h"
#include "Paragraph.h"
class BView;
@@ -164,7 +168,8 @@ public:
float extraGlyphSpacing;
float extraWhiteSpacing;
TextSpanList layoutedSpans;
std::vector<TextSpan>
layoutedSpans;
};
@@ -234,8 +239,11 @@ private:
void _GetEmptyLayoutBounds(float& x1, float& y1,
float& x2, float& y2) const;
void _AppendTextSpans(const Paragraph& paragraph);
private:
TextSpanList fTextSpans;
std::vector<TextSpan>
fTextSpans;
ParagraphStyle fParagraphStyle;
float fWidth;
+22 -25
View File
@@ -1,5 +1,6 @@
/*
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@@ -7,6 +8,7 @@
#include <algorithm>
#include <stdio.h>
#include <vector>
TextDocument::TextDocument()
@@ -164,15 +166,14 @@ TextDocument::CharacterStyleAt(int32 textOffset) const
const Paragraph& paragraph = ParagraphAt(textOffset, paragraphOffset);
textOffset -= paragraphOffset;
const TextSpanList& spans = paragraph.TextSpans();
int32 index;
int32 count = paragraph.CountTextSpans();
int32 index = 0;
while (index < spans.CountItems()) {
const TextSpan& span = spans.ItemAtFast(index);
for (index = 0; index < count; index++) {
const TextSpan& span = paragraph.TextSpanAtIndex(index);
if (textOffset - span.CountChars() < 0)
return span.Style();
textOffset -= span.CountChars();
index++;
}
return fDefaultCharacterStyle;
@@ -468,10 +469,10 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
Paragraph paragraph2(document->ParagraphAt(
document->CountParagraphs() - 1).Style());
{
const TextSpanList& textSpans = ParagraphAt(index).TextSpans();
int32 spanCount = textSpans.CountItems();
const Paragraph& paragraphAtIndex = ParagraphAt(index);
int32 spanCount = paragraphAtIndex.CountTextSpans();
for (int32 i = 0; i < spanCount; i++) {
const TextSpan& span = textSpans.ItemAtFast(i);
const TextSpan& span = paragraphAtIndex.TextSpanAtIndex(i);
int32 spanLength = span.CountChars();
if (textOffset >= spanLength) {
if (!paragraph1.Append(span))
@@ -499,10 +500,9 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
// paragraph at insert position
{
const Paragraph& otherParagraph = document->ParagraphAt(0);
const TextSpanList& textSpans = otherParagraph.TextSpans();
int32 spanCount = textSpans.CountItems();
int32 spanCount = otherParagraph.CountTextSpans();
for (int32 i = 0; i < spanCount; i++) {
const TextSpan& span = textSpans.ItemAtFast(i);
const TextSpan& span = otherParagraph.TextSpanAtIndex(i);
// TODO: Import/map CharacterStyles
if (!paragraph1.Append(span))
return B_NO_MEMORY;
@@ -531,10 +531,9 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
if (!fParagraphs.Add(otherParagraph, ++index))
return B_NO_MEMORY;
} else {
const TextSpanList& textSpans = otherParagraph.TextSpans();
int32 spanCount = textSpans.CountItems();
int32 spanCount = otherParagraph.CountTextSpans();
for (int32 i = 0; i < spanCount; i++) {
const TextSpan& span = textSpans.ItemAtFast(i);
const TextSpan& span = otherParagraph.TextSpanAtIndex(i);
// TODO: Import/map CharacterStyles
if (!paragraph2.Prepend(span))
return B_NO_MEMORY;
@@ -548,8 +547,8 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
// if its empty. This handles the case of inserting a
// line-break at the end of the document. It than needs to
// have a new, empty paragraph at the end.
const TextSpanList& spans = paragraph1.TextSpans();
const TextSpan& span = spans.LastItem();
const int32 indexLastSpan = paragraph1.CountTextSpans() - 1;
const TextSpan& span = paragraph1.TextSpanAtIndex(indexLastSpan);
if (!paragraph2.Append(TextSpan("", span.Style())))
return B_NO_MEMORY;
}
@@ -562,10 +561,9 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
Paragraph paragraph(ParagraphAt(index));
const Paragraph& otherParagraph = document->ParagraphAt(0);
const TextSpanList& textSpans = otherParagraph.TextSpans();
int32 spanCount = textSpans.CountItems();
int32 spanCount = otherParagraph.CountTextSpans();
for (int32 i = 0; i < spanCount; i++) {
const TextSpan& span = textSpans.ItemAtFast(i);
const TextSpan& span = otherParagraph.TextSpanAtIndex(i);
paragraph.Insert(textOffset, span);
textOffset += span.CountChars();
}
@@ -618,10 +616,10 @@ TextDocument::_Remove(int32 textOffset, int32 length, int32& index,
// Line break between paragraphs got removed. Shift the next
// paragraph's text spans into the resulting one.
const TextSpanList& textSpans = ParagraphAt(index + 1).TextSpans();
int32 spanCount = textSpans.CountItems();
const Paragraph& paragraph = ParagraphAt(index + 1);
int32 spanCount = paragraph.CountTextSpans();
for (int32 i = 0; i < spanCount; i++) {
const TextSpan& span = textSpans.ItemAtFast(i);
const TextSpan& span = paragraph.TextSpanAtIndex(i);
resultParagraph.Append(span);
}
fParagraphs.Remove(index + 1);
@@ -650,10 +648,9 @@ TextDocument::_Remove(int32 textOffset, int32 length, int32& index,
return B_NO_MEMORY;
// Transfer remaining spans to resultParagraph
const TextSpanList& textSpans = newParagraph.TextSpans();
int32 spanCount = textSpans.CountItems();
int32 spanCount = newParagraph.CountTextSpans();
for (int32 i = 0; i < spanCount; i++) {
const TextSpan& span = textSpans.ItemAtFast(i);
const TextSpan& span = newParagraph.TextSpanAtIndex(i);
resultParagraph.Append(span);
}