From 3d2fd2acaf1ed103639675b3116c2ac874aa174d Mon Sep 17 00:00:00 2001 From: Andrew Lindesay Date: Thu, 18 Feb 2021 22:48:51 +1300 Subject: [PATCH] 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 --- src/apps/haikudepot/textview/Paragraph.cpp | 160 +++++++++++------- src/apps/haikudepot/textview/Paragraph.h | 14 +- .../haikudepot/textview/ParagraphLayout.cpp | 38 +++-- .../haikudepot/textview/ParagraphLayout.h | 14 +- src/apps/haikudepot/textview/TextDocument.cpp | 47 +++-- 5 files changed, 161 insertions(+), 112 deletions(-) diff --git a/src/apps/haikudepot/textview/Paragraph.cpp b/src/apps/haikudepot/textview/Paragraph.cpp index d1d9649af4..f90aa175b8 100644 --- a/src/apps/haikudepot/textview/Paragraph.cpp +++ b/src/apps/haikudepot/textview/Paragraph.cpp @@ -1,5 +1,6 @@ /* * Copyright 2013-2014, Stephan Aßmus . + * Copyright 2021, Andrew Lindesay . * 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(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(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(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(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(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(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::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::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::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(fTextSpans.size()); if (spanCount == 0) { printf("

\n"); return; } printf("

\n"); for (int32 i = 0; i < spanCount; i++) { - const TextSpan& span = fTextSpans.ItemAtFast(i); + const TextSpan& span = fTextSpans[i]; if (span.CountChars() == 0) printf(" \n"); else { diff --git a/src/apps/haikudepot/textview/Paragraph.h b/src/apps/haikudepot/textview/Paragraph.h index f6d953cbec..4a2870ce4f 100644 --- a/src/apps/haikudepot/textview/Paragraph.h +++ b/src/apps/haikudepot/textview/Paragraph.h @@ -1,18 +1,17 @@ /* * Copyright 2013-2014, Stephan Aßmus . + * Copyright 2021, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef PARAGRAPH_H #define PARAGRAPH_H -#include "List.h" +#include + #include "ParagraphStyle.h" #include "TextSpan.h" -typedef List 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 + fTextSpans; mutable int32 fCachedLength; }; diff --git a/src/apps/haikudepot/textview/ParagraphLayout.cpp b/src/apps/haikudepot/textview/ParagraphLayout.cpp index 09341eda5f..27f4912f0a 100644 --- a/src/apps/haikudepot/textview/ParagraphLayout.cpp +++ b/src/apps/haikudepot/textview/ParagraphLayout.cpp @@ -8,6 +8,7 @@ * Marc Flerackers, mflerackers@androme.be * Hiroshi Lockheimer (BTextView is based on his STEEngine) * Oliver Tappe, zooey@hirschkaefer.de + * Andrew Lindesay, apl@lindesay.co.nz */ #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::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(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)); +} diff --git a/src/apps/haikudepot/textview/ParagraphLayout.h b/src/apps/haikudepot/textview/ParagraphLayout.h index 4cc46df80c..57821bfdd2 100644 --- a/src/apps/haikudepot/textview/ParagraphLayout.h +++ b/src/apps/haikudepot/textview/ParagraphLayout.h @@ -1,16 +1,20 @@ /* * Copyright 2013, Stephan Aßmus . + * Copyright 2021, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef PARAGRAPH_LAYOUT_H #define PARAGRAPH_LAYOUT_H +#include + #include #include #include -#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 + 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 + fTextSpans; ParagraphStyle fParagraphStyle; float fWidth; diff --git a/src/apps/haikudepot/textview/TextDocument.cpp b/src/apps/haikudepot/textview/TextDocument.cpp index f89bf92a04..f245c0b3a9 100644 --- a/src/apps/haikudepot/textview/TextDocument.cpp +++ b/src/apps/haikudepot/textview/TextDocument.cpp @@ -1,5 +1,6 @@ /* * Copyright 2013-2014, Stephan Aßmus . + * Copyright 2021, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -7,6 +8,7 @@ #include #include +#include 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); }