HaikuDepot: Remove Custom List

Closes #15534

Change-Id: I23fa60145607c3e8f25552f24c5e2c630b940537
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3758
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Andrew Lindesay 2021-03-01 23:02:30 +13:00
parent 0b69420bc8
commit dfbcbde1e1
18 changed files with 268 additions and 827 deletions

View File

@ -1,408 +0,0 @@
/*
* Copyright 2009-2013, Stephan Aßmus <superstippi@gmx.de>
* Copyright 2018, Andrew Lindesay <apl@lindesay.co.nz>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef LIST_H
#define LIST_H
#include <new>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SupportDefs.h>
#define BINARY_SEARCH_LINEAR_THRESHOLD 4
template <typename ItemType, bool PlainOldData, uint32 BlockSize = 8>
class List {
typedef List<ItemType, PlainOldData, BlockSize> SelfType;
typedef int32 (*CompareItemFn)(const ItemType& one, const ItemType& two);
typedef int32 (*CompareContextFn)(const void* context,
const ItemType& item);
public:
List()
:
fItems(NULL),
fCount(0),
fAllocatedCount(0),
fCompareItemsFunction(NULL),
fCompareContextFunction(NULL)
{
}
List(CompareItemFn compareItemsFunction,
CompareContextFn compareContextFunction)
:
fItems(NULL),
fCount(0),
fAllocatedCount(0),
fCompareItemsFunction(compareItemsFunction),
fCompareContextFunction(compareContextFunction)
{
}
List(const SelfType& other)
:
fItems(NULL),
fCount(0),
fAllocatedCount(0),
fCompareItemsFunction(other.fCompareItemsFunction),
fCompareContextFunction(other.fCompareContextFunction)
{
_AddAllVerbatim(other);
}
virtual ~List()
{
if (!PlainOldData) {
// Make sure to call destructors of old objects.
_Resize(0);
}
free(fItems);
}
SelfType& operator=(const SelfType& other)
{
if (this != &other)
_AddAllVerbatim(other);
return *this;
}
bool operator==(const SelfType& other) const
{
if (this == &other)
return true;
if (fCount != other.fCount)
return false;
if (fCount == 0)
return true;
if (PlainOldData) {
return memcmp(fItems, other.fItems,
fCount * sizeof(ItemType)) == 0;
} else {
for (uint32 i = 0; i < other.fCount; i++) {
if (ItemAtFast(i) != other.ItemAtFast(i))
return false;
}
}
return true;
}
bool operator!=(const SelfType& other) const
{
return !(*this == other);
}
inline void Clear()
{
_Resize(0);
}
inline bool IsEmpty() const
{
return fCount == 0;
}
inline int32 CountItems() const
{
return fCount;
}
/*! Note that the use of this method will depend on the list being sorted.
*/
inline int32 Search(const void* context) const
{
if (fCount == 0 || fCompareContextFunction == NULL)
return -1;
return _BinarySearchBounded(context, 0, fCount - 1);
}
/*! This function will add the item into the list. If the list is sorted
then the item will be insert in order. If the list is not sorted then
the item will be inserted at the end of the list.
*/
inline bool Add(const ItemType& copyFrom)
{
if (fCompareItemsFunction != NULL) {
return _AddOrdered(copyFrom);
}
return _AddTail(copyFrom);
}
inline bool Add(const ItemType& copyFrom, int32 index)
{
// if the list is sorted then ignore the index and just insert in
// order.
if (fCompareItemsFunction != NULL) {
return _AddOrdered(copyFrom);
}
return _AddAtIndex(copyFrom, index);
}
inline bool Remove()
{
if (fCount > 0) {
_Resize(fCount - 1);
return true;
}
return false;
}
inline bool Remove(int32 index)
{
if (index < 0 || index >= (int32)fCount)
return false;
if (!PlainOldData) {
ItemType* object = fItems + index;
object->~ItemType();
}
int32 nextIndex = index + 1;
if ((int32)fCount > nextIndex) {
memcpy(fItems + index, fItems + nextIndex,
(fCount - nextIndex) * sizeof(ItemType));
}
fCount--;
return true;
}
inline bool Remove(const ItemType& item)
{
return Remove(IndexOf(item));
}
inline bool Replace(int32 index, const ItemType& copyFrom)
{
if (fCompareItemsFunction != NULL) {
bool result = Remove(index);
_AddOrdered(copyFrom);
return result;
}
if (index < 0 || index >= (int32)fCount)
return false;
ItemType* item = fItems + index;
// Initialize the new object from the original.
if (!PlainOldData) {
item->~ItemType();
new (item) ItemType(copyFrom);
} else
*item = copyFrom;
return true;
}
inline const ItemType& ItemAt(int32 index) const
{
if (index < 0 || index >= (int32)fCount)
return fNullItem;
return ItemAtFast(index);
}
inline const ItemType& ItemAtFast(int32 index) const
{
return *(fItems + index);
}
inline const ItemType& LastItem() const
{
if (fCount == 0)
return fNullItem;
return ItemAt((int32)fCount - 1);
}
inline int32 IndexOf(const ItemType& item) const
{
for (uint32 i = 0; i < fCount; i++) {
if (ItemAtFast(i) == item)
return i;
}
return -1;
}
inline bool Contains(const ItemType& item) const
{
return IndexOf(item) >= 0;
}
private:
inline int32 _BinarySearchLinearBounded(
const void* context,
int32 start, int32 end) const
{
for(int32 i = start; i <= end; i++) {
if (fCompareContextFunction(context, ItemAtFast(i)) == 0)
return i;
}
return -1;
}
inline int32 _BinarySearchBounded(
const void* context, int32 start, int32 end) const
{
if (end - start < BINARY_SEARCH_LINEAR_THRESHOLD)
return _BinarySearchLinearBounded(context, start, end);
int32 mid = start + ((end - start) >> 1);
if (fCompareContextFunction(context, ItemAtFast(mid)) >= 0)
return _BinarySearchBounded(context, mid, end);
return _BinarySearchBounded(context, start, mid - 1);
}
inline void _AddAllVerbatim(const SelfType& other)
{
if (PlainOldData) {
if (_Resize(other.fCount))
memcpy(fItems, other.fItems, fCount * sizeof(ItemType));
} else {
// Make sure to call destructors of old objects.
// NOTE: Another option would be to use
// ItemType::operator=(const ItemType& other), but then
// we would need to be careful which objects are already
// initialized. Also ItemType would be required to implement the
// operator, while doing it this way requires only a copy
// constructor.
_Resize(0);
for (uint32 i = 0; i < other.fCount; i++) {
if (!Add(other.ItemAtFast(i)))
break;
}
}
}
inline bool _AddOrderedLinearBounded(
const ItemType& copyFrom, int32 start, int32 end)
{
for(int32 i = start; i <= (end + 1); i++) {
bool greaterBefore = (i == start)
|| (fCompareItemsFunction(copyFrom, ItemAtFast(i - 1)) > 0);
if (greaterBefore) {
bool lessAfter = (i == end + 1)
|| (fCompareItemsFunction(copyFrom, ItemAtFast(i)) <= 0);
if (lessAfter)
return _AddAtIndex(copyFrom, i);
}
}
printf("illegal state; unable to insert item into list\n");
exit(EXIT_FAILURE);
}
inline bool _AddOrderedBounded(
const ItemType& copyFrom, int32 start, int32 end)
{
if(end - start < BINARY_SEARCH_LINEAR_THRESHOLD)
return _AddOrderedLinearBounded(copyFrom, start, end);
int32 mid = start + ((end - start) >> 1);
if (fCompareItemsFunction(copyFrom, ItemAtFast(mid)) >= 0)
return _AddOrderedBounded(copyFrom, mid, end);
return _AddOrderedBounded(copyFrom, start, mid - 1);
}
inline bool _AddTail(const ItemType& copyFrom)
{
if (_Resize(fCount + 1)) {
ItemType* item = fItems + fCount - 1;
// Initialize the new object from the original.
if (!PlainOldData)
new (item) ItemType(copyFrom);
else
*item = copyFrom;
return true;
}
return false;
}
inline bool _AddAtIndex(const ItemType& copyFrom, int32 index)
{
if (index < 0 || index > (int32)fCount)
return false;
if (!_Resize(fCount + 1))
return false;
int32 nextIndex = index + 1;
if ((int32)fCount > nextIndex)
memmove(fItems + nextIndex, fItems + index,
(fCount - nextIndex) * sizeof(ItemType));
ItemType* item = fItems + index;
if (!PlainOldData)
new (item) ItemType(copyFrom);
else
*item = copyFrom;
return true;
}
inline bool _AddOrdered(const ItemType& copyFrom)
{
// special case
if (fCount == 0
|| fCompareItemsFunction(copyFrom, ItemAtFast(fCount - 1)) > 0) {
return _AddTail(copyFrom);
}
return _AddOrderedBounded(copyFrom, 0, fCount - 1);
}
inline bool _Resize(uint32 count)
{
if (count > fAllocatedCount) {
uint32 allocationCount = (count + BlockSize - 1)
/ BlockSize * BlockSize;
ItemType* items = reinterpret_cast<ItemType*>(
realloc(fItems, allocationCount * sizeof(ItemType)));
if (items == NULL)
return false;
fItems = items;
fAllocatedCount = allocationCount;
} else if (count < fCount) {
if (!PlainOldData) {
// Uninit old objects so that we can re-use them when
// appending objects without the need to re-allocate.
for (uint32 i = count; i < fCount; i++) {
ItemType* object = fItems + i;
object->~ItemType();
}
}
}
fCount = count;
return true;
}
ItemType* fItems;
ItemType fNullItem;
uint32 fCount;
uint32 fAllocatedCount;
CompareItemFn fCompareItemsFunction;
CompareContextFn fCompareContextFunction;
};
#endif // LIST_H

View File

@ -252,16 +252,13 @@ PackageIconTarRepository::GetIcon(const BString& pkgName, BitmapSize size,
else {
HashString key = _ToIconCacheKey(pkgName, actualSize);
// TODO; need to implement an LRU cache so that not too many icons are
// in memory at the same time.
if (!fIconCache.ContainsKey(key)) {
result = _CreateIconFromTarOffset(iconDataTarOffset, bitmap);
if (result == B_OK)
fIconCache.Put(key, bitmap);
else {
HDERROR("failure to read image for package [%s] at offset %"
B_PRIdSSIZE, pkgName.String(), iconDataTarOffset);
B_PRIdOFF, pkgName.String(), iconDataTarOffset);
fIconCache.Put(key, sDefaultIcon);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017-2020, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2017-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -247,8 +247,6 @@ ServerHelper::GetFailuresFromJsonRpcError(
ValidationFailures& failures, BMessage& responseEnvelopeMessage)
{
BMessage errorMessage;
int32 errorCode = WebAppInterface::ErrorCodeFromResponse(
responseEnvelopeMessage);
if (responseEnvelopeMessage.FindMessage("error", &errorMessage) == B_OK) {
BMessage dataMessage;
@ -285,4 +283,4 @@ ServerHelper::_GetFailuresFromJsonRpcFailures(
failures.AddFailure(property, message);
}
}
}
}

View File

@ -95,9 +95,9 @@ get_char_classification(uint32 charCode)
inline bool
can_end_line(const GlyphInfoList& glyphInfos, int offset)
can_end_line(const std::vector<GlyphInfo>& glyphInfos, int offset)
{
int count = glyphInfos.CountItems();
int count = static_cast<int>(glyphInfos.size());
if (offset == count - 1)
return true;
@ -105,14 +105,14 @@ can_end_line(const GlyphInfoList& glyphInfos, int offset)
if (offset < 0 || offset > count)
return false;
uint32 charCode = glyphInfos.ItemAtFast(offset).charCode;
uint32 charCode = glyphInfos[offset].charCode;
uint32 classification = get_char_classification(charCode);
// wrapping is always allowed at end of text and at newlines
if (classification == CHAR_CLASS_END_OF_TEXT || charCode == '\n')
return true;
uint32 nextCharCode = glyphInfos.ItemAtFast(offset + 1).charCode;
uint32 nextCharCode = glyphInfos[offset + 1].charCode;
uint32 nextClassification = get_char_classification(nextCharCode);
// never separate a punctuation char from its preceding word
@ -241,8 +241,8 @@ ParagraphLayout::Height()
float height = 0.0f;
if (fLineInfos.CountItems() > 0) {
const LineInfo& lastLine = fLineInfos.LastItem();
if (!fLineInfos.empty()) {
const LineInfo& lastLine = fLineInfos[fLineInfos.size() - 1];
height = lastLine.y + lastLine.height;
}
@ -255,9 +255,9 @@ ParagraphLayout::Draw(BView* view, const BPoint& offset)
{
_ValidateLayout();
int lineCount = fLineInfos.CountItems();
int lineCount = static_cast<int>(fLineInfos.size());
for (int i = 0; i < lineCount; i++) {
const LineInfo& line = fLineInfos.ItemAtFast(i);
const LineInfo& line = fLineInfos[i];
_DrawLine(view, offset, line);
}
@ -268,7 +268,7 @@ ParagraphLayout::Draw(BView* view, const BPoint& offset)
BPoint bulletPos(offset);
bulletPos.x += fParagraphStyle.FirstLineInset()
+ fParagraphStyle.LineInset();
bulletPos.y += fLineInfos.ItemAt(0).maxAscent;
bulletPos.y += fLineInfos[0].maxAscent;
view->DrawString(bullet.String(), bulletPos);
}
}
@ -277,7 +277,7 @@ ParagraphLayout::Draw(BView* view, const BPoint& offset)
int32
ParagraphLayout::CountGlyphs() const
{
return fGlyphInfos.CountItems();
return static_cast<int32>(fGlyphInfos.size());
}
@ -285,7 +285,7 @@ int32
ParagraphLayout::CountLines()
{
_ValidateLayout();
return fLineInfos.CountItems();
return static_cast<int32>(fLineInfos.size());
}
@ -294,18 +294,18 @@ ParagraphLayout::LineIndexForOffset(int32 textOffset)
{
_ValidateLayout();
if (fGlyphInfos.CountItems() == 0)
if (fGlyphInfos.empty())
return 0;
if (textOffset >= fGlyphInfos.CountItems()) {
const GlyphInfo& glyph = fGlyphInfos.LastItem();
if (textOffset >= static_cast<int32>(fGlyphInfos.size())) {
const GlyphInfo& glyph = fGlyphInfos[fGlyphInfos.size() - 1];
return glyph.lineIndex;
}
if (textOffset < 0)
textOffset = 0;
const GlyphInfo& glyph = fGlyphInfos.ItemAtFast(textOffset);
const GlyphInfo& glyph = fGlyphInfos[textOffset];
return glyph.lineIndex;
}
@ -317,10 +317,11 @@ ParagraphLayout::FirstOffsetOnLine(int32 lineIndex)
if (lineIndex < 0)
lineIndex = 0;
if (lineIndex >= fLineInfos.CountItems())
lineIndex = fLineInfos.CountItems() - 1;
int32 countLineInfos = static_cast<int32>(fLineInfos.size());
if (lineIndex >= countLineInfos)
lineIndex = countLineInfos - 1;
return fLineInfos.ItemAt(lineIndex).textOffset;
return fLineInfos[lineIndex].textOffset;
}
@ -332,10 +333,10 @@ ParagraphLayout::LastOffsetOnLine(int32 lineIndex)
if (lineIndex < 0)
lineIndex = 0;
if (lineIndex >= fLineInfos.CountItems() - 1)
if (lineIndex >= static_cast<int32>(fLineInfos.size()) - 1)
return CountGlyphs() - 1;
return fLineInfos.ItemAt(lineIndex + 1).textOffset - 1;
return fLineInfos[lineIndex + 1].textOffset - 1;
}
@ -345,27 +346,28 @@ ParagraphLayout::GetLineBounds(int32 lineIndex, float& x1, float& y1,
{
_ValidateLayout();
if (fGlyphInfos.CountItems() == 0) {
if (fGlyphInfos.empty()) {
_GetEmptyLayoutBounds(x1, y1, x2, y2);
return;
}
if (lineIndex < 0)
lineIndex = 0;
if (lineIndex >= fLineInfos.CountItems())
lineIndex = fLineInfos.CountItems() - 1;
int32 countLineInfos = static_cast<int32>(fLineInfos.size());
if (lineIndex >= countLineInfos)
lineIndex = countLineInfos - 1;
const LineInfo& lineInfo = fLineInfos.ItemAt(lineIndex);
const LineInfo& lineInfo = fLineInfos[lineIndex];
int32 firstGlyphIndex = lineInfo.textOffset;
int32 lastGlyphIndex;
if (lineIndex < fLineInfos.CountItems() - 1)
lastGlyphIndex = fLineInfos.ItemAt(lineIndex + 1).textOffset - 1;
if (lineIndex < countLineInfos - 1)
lastGlyphIndex = fLineInfos[lineIndex + 1].textOffset - 1;
else
lastGlyphIndex = fGlyphInfos.CountItems() - 1;
lastGlyphIndex = static_cast<int32>(fGlyphInfos.size()) - 1;
const GlyphInfo& firstInfo = fGlyphInfos.ItemAtFast(firstGlyphIndex);
const GlyphInfo& lastInfo = fGlyphInfos.ItemAtFast(lastGlyphIndex);
const GlyphInfo& firstInfo = fGlyphInfos[firstGlyphIndex];
const GlyphInfo& lastInfo = fGlyphInfos[lastGlyphIndex];
x1 = firstInfo.x;
y1 = lineInfo.y;
@ -380,14 +382,14 @@ ParagraphLayout::GetTextBounds(int32 textOffset, float& x1, float& y1,
{
_ValidateLayout();
if (fGlyphInfos.CountItems() == 0) {
if (fGlyphInfos.empty()) {
_GetEmptyLayoutBounds(x1, y1, x2, y2);
return;
}
if (textOffset >= fGlyphInfos.CountItems()) {
const GlyphInfo& glyph = fGlyphInfos.LastItem();
const LineInfo& line = fLineInfos.ItemAt(glyph.lineIndex);
if (textOffset >= static_cast<int32>(fGlyphInfos.size())) {
const GlyphInfo& glyph = fGlyphInfos[fGlyphInfos.size() - 1];
const LineInfo& line = fLineInfos[glyph.lineIndex];
x1 = glyph.x + glyph.width;
x2 = x1;
@ -400,8 +402,8 @@ ParagraphLayout::GetTextBounds(int32 textOffset, float& x1, float& y1,
if (textOffset < 0)
textOffset = 0;
const GlyphInfo& glyph = fGlyphInfos.ItemAtFast(textOffset);
const LineInfo& line = fLineInfos.ItemAt(glyph.lineIndex);
const GlyphInfo& glyph = fGlyphInfos[textOffset];
const LineInfo& line = fLineInfos[glyph.lineIndex];
x1 = glyph.x;
x2 = x1 + glyph.width;
@ -417,19 +419,19 @@ ParagraphLayout::TextOffsetAt(float x, float y, bool& rightOfCenter)
rightOfCenter = false;
int32 lineCount = fLineInfos.CountItems();
if (fGlyphInfos.CountItems() == 0 || lineCount == 0
|| fLineInfos.ItemAtFast(0).y > y) {
int32 lineCount = static_cast<int32>(fLineInfos.size());
if (fGlyphInfos.empty() || lineCount == 0
|| fLineInfos[0].y > y) {
// Above first line or empty text
return 0;
}
int32 lineIndex = 0;
if (floorf(fLineInfos.LastItem().y
+ fLineInfos.LastItem().height + 0.5) > y) {
LineInfo lastLineInfo = fLineInfos[fLineInfos.size() - 1];
if (floorf(lastLineInfo.y + lastLineInfo.height + 0.5) > y) {
// TODO: Optimize, can binary search line here:
for (; lineIndex < lineCount; lineIndex++) {
const LineInfo& line = fLineInfos.ItemAtFast(lineIndex);
const LineInfo& line = fLineInfos[lineIndex];
float lineBottom = floorf(line.y + line.height + 0.5);
if (lineBottom > y)
break;
@ -439,17 +441,17 @@ ParagraphLayout::TextOffsetAt(float x, float y, bool& rightOfCenter)
}
// Found line
const LineInfo& line = fLineInfos.ItemAtFast(lineIndex);
const LineInfo& line = fLineInfos[lineIndex];
int32 textOffset = line.textOffset;
int32 end;
if (lineIndex < lineCount - 1)
end = fLineInfos.ItemAtFast(lineIndex + 1).textOffset - 1;
end = fLineInfos[lineIndex + 1].textOffset - 1;
else
end = fGlyphInfos.CountItems() - 1;
end = fGlyphInfos.size() - 1;
// TODO: Optimize, can binary search offset here:
for (; textOffset <= end; textOffset++) {
const GlyphInfo& glyph = fGlyphInfos.ItemAtFast(textOffset);
const GlyphInfo& glyph = fGlyphInfos[textOffset];
float x1 = glyph.x;
if (x1 > x)
return textOffset;
@ -461,7 +463,7 @@ ParagraphLayout::TextOffsetAt(float x, float y, bool& rightOfCenter)
// x2 in case the line is justified.
float x3;
if (textOffset < end - 1)
x3 = fGlyphInfos.ItemAtFast(textOffset + 1).x;
x3 = fGlyphInfos[textOffset + 1].x;
else
x3 = x2;
@ -473,7 +475,7 @@ ParagraphLayout::TextOffsetAt(float x, float y, bool& rightOfCenter)
// Account for trailing line break at end of line, the
// returned offset should be before that.
rightOfCenter = fGlyphInfos.ItemAtFast(end).charCode != '\n';
rightOfCenter = fGlyphInfos[end].charCode != '\n';
return end;
}
@ -485,7 +487,7 @@ ParagraphLayout::TextOffsetAt(float x, float y, bool& rightOfCenter)
void
ParagraphLayout::_Init()
{
fGlyphInfos.Clear();
fGlyphInfos.clear();
std::vector<TextSpan>::const_iterator it;
for (it = fTextSpans.begin(); it != fTextSpans.end(); it++) {
@ -512,7 +514,7 @@ ParagraphLayout::_ValidateLayout()
void
ParagraphLayout::_Layout()
{
fLineInfos.Clear();
fLineInfos.clear();
const Bullet& bullet = fParagraphStyle.Bullet();
@ -522,9 +524,9 @@ ParagraphLayout::_Layout()
int lineIndex = 0;
int lineStart = 0;
int glyphCount = fGlyphInfos.CountItems();
int glyphCount = static_cast<int>(fGlyphInfos.size());
for (int i = 0; i < glyphCount; i++) {
GlyphInfo glyph = fGlyphInfos.ItemAtFast(i);
GlyphInfo glyph = fGlyphInfos[i];
uint32 charClassification = get_char_classification(glyph.charCode);
@ -565,9 +567,9 @@ ParagraphLayout::_Layout()
nextLine = true;
lineBreak = true;
glyph.x = x;
fGlyphInfos.Replace(i, glyph);
fGlyphInfos[i] = glyph;
} else if (fWidth > 0.0f && x + advanceX > fWidth) {
fGlyphInfos.Replace(i, glyph);
fGlyphInfos[i] = glyph;
if (charClassification == CHAR_CLASS_WHITESPACE) {
advanceX = 0.0f;
} else if (i > lineStart) {
@ -587,7 +589,7 @@ ParagraphLayout::_Layout()
// Adjust the glyph info to point at the changed buffer
// position
glyph = fGlyphInfos.ItemAtFast(i);
glyph = fGlyphInfos[i];
advanceX = glyph.width;
} else {
// Just break where we are.
@ -623,7 +625,7 @@ ParagraphLayout::_Layout()
if (!lineBreak && i < glyphCount) {
glyph.x = x;
fGlyphInfos.Replace(i, glyph);
fGlyphInfos[i] = glyph;
}
x += advanceX;
@ -649,7 +651,7 @@ ParagraphLayout::_ApplyAlignment()
if (alignment == ALIGN_LEFT && !justify)
return;
int glyphCount = fGlyphInfos.CountItems();
int glyphCount = static_cast<int>(fGlyphInfos.size());
if (glyphCount == 0)
return;
@ -663,7 +665,7 @@ ParagraphLayout::_ApplyAlignment()
// the position of the character determines the available space to be
// distributed (spaceLeft).
for (int i = glyphCount - 1; i >= 0; i--) {
GlyphInfo glyph = fGlyphInfos.ItemAtFast(i);
GlyphInfo glyph = fGlyphInfos[i];
if (glyph.lineIndex != lineIndex) {
bool lineBreak = glyph.charCode == '\n' || i == glyphCount - 1;
@ -695,7 +697,7 @@ ParagraphLayout::_ApplyAlignment()
int charCount = 0;
int spaceCount = 0;
for (int j = i; j >= 0; j--) {
const GlyphInfo& previousGlyph = fGlyphInfos.ItemAtFast(j);
const GlyphInfo& previousGlyph = fGlyphInfos[j];
if (previousGlyph.lineIndex != lineIndex) {
j++;
break;
@ -737,11 +739,11 @@ ParagraphLayout::_ApplyAlignment()
if (charCount > 0)
charSpace = spaceLeftForChars / charCount;
LineInfo line = fLineInfos.ItemAtFast(lineIndex);
LineInfo line = fLineInfos[lineIndex];
line.extraGlyphSpacing = charSpace;
line.extraWhiteSpacing = whiteSpace;
fLineInfos.Replace(lineIndex, line);
fLineInfos[lineIndex] = line;
}
}
@ -754,7 +756,7 @@ ParagraphLayout::_ApplyAlignment()
unsigned classification = get_char_classification(glyph.charCode);
if (i < glyphCount - 1) {
GlyphInfo nextGlyph = fGlyphInfos.ItemAtFast(i + 1);
GlyphInfo nextGlyph = fGlyphInfos[i + 1];
if (nextGlyph.lineIndex == lineIndex) {
uint32 nextClassification
= get_char_classification(nextGlyph.charCode);
@ -765,12 +767,12 @@ ParagraphLayout::_ApplyAlignment()
// character
float shift = (nextGlyph.x - glyph.x) - glyph.width;
nextGlyph.x -= shift;
fGlyphInfos.Replace(i + 1, nextGlyph);
fGlyphInfos[i + 1] = nextGlyph;
}
}
}
fGlyphInfos.Replace(i, glyph);
fGlyphInfos[i] = glyph;
// The shift (spaceLeft) is reduced depending on the character
// classification.
@ -830,7 +832,16 @@ ParagraphLayout::_AppendGlyphInfo(uint32 charCode, float width,
width += style.GlyphSpacing();
return fGlyphInfos.Add(GlyphInfo(charCode, 0.0f, width, 0));
try {
fGlyphInfos.push_back(GlyphInfo(charCode, 0.0f, width, 0));
}
catch (std::bad_alloc& ba) {
fprintf(stderr, "bad_alloc occurred adding glyph info to a "
"paragraph\n");
return false;
}
return true;
}
@ -846,9 +857,9 @@ ParagraphLayout::_FinalizeLine(int lineStart, int lineEnd, int lineIndex,
for (int i = lineStart; i <= lineEnd; i++) {
// Mark line index in glyph
GlyphInfo glyph = fGlyphInfos.ItemAtFast(i);
GlyphInfo glyph = fGlyphInfos[i];
glyph.lineIndex = lineIndex;
fGlyphInfos.Replace(i, glyph);
fGlyphInfos[i] = glyph;
// See if the next sub-span needs to be added to the LineInfo
bool addSpan = false;
@ -870,7 +881,7 @@ ParagraphLayout::_FinalizeLine(int lineStart, int lineEnd, int lineIndex,
}
}
if (fGlyphInfos.CountItems() == 0 && !fTextSpans.empty()) {
if (fGlyphInfos.empty() && !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.
@ -881,7 +892,15 @@ ParagraphLayout::_FinalizeLine(int lineStart, int lineEnd, int lineIndex,
lineHeight = line.height;
return fLineInfos.Add(line);
try {
fLineInfos.push_back(line);
}
catch (std::bad_alloc& ba) {
fprintf(stderr, "bad_alloc occurred adding line to line infos\n");
return false;
}
return true;
}
@ -928,8 +947,8 @@ ParagraphLayout::_DrawSpan(BView* view, BPoint offset,
if (text.Length() == 0)
return;
const GlyphInfo& glyph = fGlyphInfos.ItemAtFast(textOffset);
const LineInfo& line = fLineInfos.ItemAtFast(glyph.lineIndex);
const GlyphInfo& glyph = fGlyphInfos[textOffset];
const LineInfo& line = fLineInfos[glyph.lineIndex];
offset.x += glyph.x;
offset.y += line.y + line.maxAscent;
@ -957,7 +976,7 @@ void
ParagraphLayout::_GetEmptyLayoutBounds(float& x1, float& y1, float& x2,
float& y2) const
{
if (fLineInfos.CountItems() == 0) {
if (fLineInfos.empty()) {
x1 = 0.0f;
y1 = 0.0f;
x2 = 0.0f;
@ -972,7 +991,7 @@ ParagraphLayout::_GetEmptyLayoutBounds(float& x1, float& y1, float& x2,
x1 = fParagraphStyle.LineInset() + fParagraphStyle.FirstLineInset()
+ bullet.Spacing();
x2 = x1;
const LineInfo& lineInfo = fLineInfos.ItemAt(0);
const LineInfo& lineInfo = fLineInfos[0];
y1 = lineInfo.y;
y2 = lineInfo.y + lineInfo.height;
}

View File

@ -81,9 +81,6 @@ public:
};
typedef List<GlyphInfo, false> GlyphInfoList;
class LineInfo {
public:
LineInfo()
@ -173,9 +170,6 @@ public:
};
typedef List<LineInfo, false> LineInfoList;
class ParagraphLayout : public BReferenceable {
public:
ParagraphLayout();
@ -249,8 +243,10 @@ private:
float fWidth;
bool fLayoutValid;
GlyphInfoList fGlyphInfos;
LineInfoList fLineInfos;
std::vector<GlyphInfo>
fGlyphInfos;
std::vector<LineInfo>
fLineInfos;
};

View File

@ -194,7 +194,14 @@ TextDocument::ParagraphStyleAt(int32 textOffset) const
int32
TextDocument::CountParagraphs() const
{
return fParagraphs.CountItems();
return fParagraphs.size();
}
const Paragraph&
TextDocument::ParagraphAtIndex(int32 index) const
{
return fParagraphs[index];
}
@ -205,9 +212,9 @@ TextDocument::ParagraphIndexFor(int32 textOffset, int32& paragraphOffset) const
// that knew there text offset in the document.
int32 textLength = 0;
paragraphOffset = 0;
int32 count = fParagraphs.CountItems();
int32 count = fParagraphs.size();
for (int32 i = 0; i < count; i++) {
const Paragraph& paragraph = fParagraphs.ItemAtFast(i);
const Paragraph& paragraph = fParagraphs[i];
int32 paragraphLength = paragraph.Length();
textLength += paragraphLength;
if (textLength > textOffset
@ -225,7 +232,7 @@ TextDocument::ParagraphAt(int32 textOffset, int32& paragraphOffset) const
{
int32 index = ParagraphIndexFor(textOffset, paragraphOffset);
if (index >= 0)
return fParagraphs.ItemAtFast(index);
return fParagraphs[index];
return fEmptyLastParagraph;
}
@ -234,8 +241,8 @@ TextDocument::ParagraphAt(int32 textOffset, int32& paragraphOffset) const
const Paragraph&
TextDocument::ParagraphAt(int32 index) const
{
if (index >= 0 && index < fParagraphs.CountItems())
return fParagraphs.ItemAtFast(index);
if (index >= 0 && index < static_cast<int32>(fParagraphs.size()))
return fParagraphs[index];
return fEmptyLastParagraph;
}
@ -243,7 +250,15 @@ TextDocument::ParagraphAt(int32 index) const
bool
TextDocument::Append(const Paragraph& paragraph)
{
return fParagraphs.Add(paragraph);
try {
fParagraphs.push_back(paragraph);
}
catch (std::bad_alloc& ba) {
fprintf(stderr, "bad_alloc when adding a paragraph to a text "
"document\n");
return false;
}
return true;
}
@ -253,9 +268,9 @@ TextDocument::Length() const
// TODO: Could be O(1) if the Paragraphs were wrapped in classes that
// knew their text offset in the document.
int32 textLength = 0;
int32 count = fParagraphs.CountItems();
int32 count = fParagraphs.size();
for (int32 i = 0; i < count; i++) {
const Paragraph& paragraph = fParagraphs.ItemAtFast(i);
const Paragraph& paragraph = fParagraphs[i];
textLength += paragraph.Length();
}
return textLength;
@ -277,9 +292,9 @@ TextDocument::Text(int32 start, int32 length) const
BString text;
int32 count = fParagraphs.CountItems();
int32 count = fParagraphs.size();
for (int32 i = 0; i < count; i++) {
const Paragraph& paragraph = fParagraphs.ItemAtFast(i);
const Paragraph& paragraph = fParagraphs[i];
int32 paragraphLength = paragraph.Length();
if (paragraphLength == 0)
continue;
@ -319,9 +334,9 @@ TextDocument::SubDocument(int32 start, int32 length) const
if (start < 0)
start = 0;
int32 count = fParagraphs.CountItems();
int32 count = fParagraphs.size();
for (int32 i = 0; i < count; i++) {
const Paragraph& paragraph = fParagraphs.ItemAtFast(i);
const Paragraph& paragraph = fParagraphs[i];
int32 paragraphLength = paragraph.Length();
if (paragraphLength == 0)
continue;
@ -355,14 +370,14 @@ TextDocument::SubDocument(int32 start, int32 length) const
void
TextDocument::PrintToStream() const
{
int32 paragraphCount = fParagraphs.CountItems();
int32 paragraphCount = fParagraphs.size();
if (paragraphCount == 0) {
printf("<document/>\n");
return;
}
printf("<document>\n");
for (int32 i = 0; i < paragraphCount; i++) {
fParagraphs.ItemAtFast(i).PrintToStream();
fParagraphs[i].PrintToStream();
}
printf("</document>\n");
}
@ -413,28 +428,46 @@ TextDocument::NormalizeText(const BString& text,
bool
TextDocument::AddListener(TextListenerRef listener)
{
return fTextListeners.Add(listener);
try {
fTextListeners.push_back(listener);
}
catch (std::bad_alloc& ba) {
fprintf(stderr, "bad_alloc when adding a listener to a text "
"document\n");
return false;
}
return true;
}
bool
TextDocument::RemoveListener(TextListenerRef listener)
{
return fTextListeners.Remove(listener);
std::remove(fTextListeners.begin(), fTextListeners.end(), listener);
return true;
}
bool
TextDocument::AddUndoListener(UndoableEditListenerRef listener)
{
return fUndoListeners.Add(listener);
try {
fUndoListeners.push_back(listener);
}
catch (std::bad_alloc& ba) {
fprintf(stderr, "bad_alloc when adding an undo listener to a text "
"document\n");
return false;
}
return true;
}
bool
TextDocument::RemoveUndoListener(UndoableEditListenerRef listener)
{
return fUndoListeners.Remove(listener);
std::remove(fUndoListeners.begin(), fUndoListeners.end(), listener);
return true;
}
@ -494,7 +527,7 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
}
}
fParagraphs.Remove(index);
fParagraphs.erase(fParagraphs.begin() + index);
// Append first paragraph in other document to first part of
// paragraph at insert position
@ -509,17 +542,26 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
}
}
// Insert the first paragraph-part again to the document
if (!fParagraphs.Add(paragraph1, index))
// Insert the first paragraph-part again to the document
try {
fParagraphs.insert(fParagraphs.begin() + index, paragraph1);
}
catch (std::bad_alloc& ba) {
return B_NO_MEMORY;
}
paragraphCount++;
// Insert the other document's paragraph save for the last one
for (int32 i = 1; i < document->CountParagraphs() - 1; i++) {
const Paragraph& otherParagraph = document->ParagraphAt(i);
// TODO: Import/map CharacterStyles and ParagraphStyle
if (!fParagraphs.Add(otherParagraph, ++index))
index++;
try {
fParagraphs.insert(fParagraphs.begin() + index, otherParagraph);
}
catch (std::bad_alloc& ba) {
return B_NO_MEMORY;
}
paragraphCount++;
}
@ -528,8 +570,13 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
const Paragraph& otherParagraph = document->ParagraphAt(lastIndex);
if (otherParagraph.EndsWith("\n")) {
// TODO: Import/map CharacterStyles and ParagraphStyle
if (!fParagraphs.Add(otherParagraph, ++index))
index++;
try {
fParagraphs.insert(fParagraphs.begin() + index, otherParagraph);
}
catch (std::bad_alloc& ba) {
return B_NO_MEMORY;
}
} else {
int32 spanCount = otherParagraph.CountTextSpans();
for (int32 i = 0; i < spanCount; i++) {
@ -553,8 +600,13 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
return B_NO_MEMORY;
}
if (!fParagraphs.Add(paragraph2, ++index))
index++;
try {
fParagraphs.insert(fParagraphs.begin() + index, paragraph2);
}
catch (std::bad_alloc& ba) {
return B_NO_MEMORY;
}
paragraphCount++;
} else {
@ -568,9 +620,7 @@ TextDocument::_Insert(int32 textOffset, TextDocumentRef document,
textOffset += span.CountChars();
}
if (!fParagraphs.Replace(index, paragraph))
return B_NO_MEMORY;
fParagraphs[index] = paragraph;
paragraphCount++;
}
@ -612,7 +662,7 @@ TextDocument::_Remove(int32 textOffset, int32 length, int32& index,
}
if (textOffset == paragraphLength && length == 0
&& index + 1 < fParagraphs.CountItems()) {
&& index + 1 < static_cast<int32>(fParagraphs.size())) {
// Line break between paragraphs got removed. Shift the next
// paragraph's text spans into the resulting one.
@ -622,13 +672,13 @@ TextDocument::_Remove(int32 textOffset, int32 length, int32& index,
const TextSpan& span = paragraph.TextSpanAtIndex(i);
resultParagraph.Append(span);
}
fParagraphs.Remove(index + 1);
fParagraphs.erase(fParagraphs.begin() + (index + 1));
paragraphCount++;
}
textOffset = 0;
while (length > 0 && index + 1 < fParagraphs.CountItems()) {
while (length > 0 && index + 1 < static_cast<int32>(fParagraphs.size())) {
paragraphCount++;
const Paragraph& paragraph = ParagraphAt(index + 1);
paragraphLength = paragraph.Length();
@ -637,12 +687,12 @@ TextDocument::_Remove(int32 textOffset, int32 length, int32& index,
// transfered to the result parahraph.
if (length >= paragraphLength) {
length -= paragraphLength;
fParagraphs.Remove(index);
fParagraphs.erase(fParagraphs.begin() + index);
} else {
// Last paragraph reached
int32 removedLength = std::min(length, paragraphLength);
Paragraph newParagraph(paragraph);
fParagraphs.Remove(index + 1);
fParagraphs.erase(fParagraphs.begin() + (index + 1));
if (!newParagraph.Remove(0, removedLength))
return B_NO_MEMORY;
@ -658,7 +708,7 @@ TextDocument::_Remove(int32 textOffset, int32 length, int32& index,
}
}
fParagraphs.Replace(index, resultParagraph);
fParagraphs[index] = resultParagraph;
return B_OK;
}
@ -672,10 +722,11 @@ TextDocument::_NotifyTextChanging(TextChangingEvent& event) const
{
// Copy listener list to have a stable list in case listeners
// are added/removed from within the notification hook.
TextListenerList listeners(fTextListeners);
int32 count = listeners.CountItems();
std::vector<TextListenerRef> listeners(fTextListeners);
int32 count = listeners.size();
for (int32 i = 0; i < count; i++) {
const TextListenerRef& listener = listeners.ItemAtFast(i);
const TextListenerRef& listener = listeners[i];
if (!listener.IsSet())
continue;
listener->TextChanging(event);
@ -690,10 +741,10 @@ TextDocument::_NotifyTextChanged(const TextChangedEvent& event) const
{
// Copy listener list to have a stable list in case listeners
// are added/removed from within the notification hook.
TextListenerList listeners(fTextListeners);
int32 count = listeners.CountItems();
std::vector<TextListenerRef> listeners(fTextListeners);
int32 count = listeners.size();
for (int32 i = 0; i < count; i++) {
const TextListenerRef& listener = listeners.ItemAtFast(i);
const TextListenerRef& listener = listeners[i];
if (!listener.IsSet())
continue;
listener->TextChanged(event);
@ -706,10 +757,10 @@ TextDocument::_NotifyUndoableEditHappened(const UndoableEditRef& edit) const
{
// Copy listener list to have a stable list in case listeners
// are added/removed from within the notification hook.
UndoListenerList listeners(fUndoListeners);
int32 count = listeners.CountItems();
std::vector<UndoableEditListenerRef> listeners(fUndoListeners);
int32 count = listeners.size();
for (int32 i = 0; i < count; i++) {
const UndoableEditListenerRef& listener = listeners.ItemAtFast(i);
const UndoableEditListenerRef& listener = listeners[i];
if (!listener.IsSet())
continue;
listener->UndoableEditHappened(this, edit);

View File

@ -14,10 +14,6 @@
#include "UndoableEditListener.h"
typedef List<Paragraph, false> ParagraphList;
typedef List<TextListenerRef, false> TextListenerList;
typedef List<UndoableEditListenerRef, false> UndoListenerList;
class TextDocument;
typedef BReference<TextDocument> TextDocumentRef;
@ -60,11 +56,8 @@ public:
const CharacterStyle& CharacterStyleAt(int32 textOffset) const;
const ParagraphStyle& ParagraphStyleAt(int32 textOffset) const;
// Paragraph access
const ParagraphList& Paragraphs() const
{ return fParagraphs; }
int32 CountParagraphs() const;
const Paragraph& ParagraphAtIndex(int32 index) const;
int32 ParagraphIndexFor(int32 textOffset,
int32& paragraphOffset) const;
@ -117,12 +110,15 @@ private:
const UndoableEditRef& edit) const;
private:
ParagraphList fParagraphs;
std::vector<Paragraph>
fParagraphs;
Paragraph fEmptyLastParagraph;
CharacterStyle fDefaultCharacterStyle;
TextListenerList fTextListeners;
UndoListenerList fUndoListeners;
std::vector<TextListenerRef>
fTextListeners;
std::vector<UndoableEditListenerRef>
fUndoListeners;
};

View File

@ -113,7 +113,7 @@ void
TextDocumentLayout::Invalidate()
{
if (fDocument.IsSet())
InvalidateParagraphs(0, fDocument->Paragraphs().CountItems());
InvalidateParagraphs(0, fDocument->CountParagraphs());
}
@ -125,24 +125,28 @@ TextDocumentLayout::InvalidateParagraphs(int32 start, int32 count)
fLayoutValid = false;
const ParagraphList& paragraphs = fDocument->Paragraphs();
while (count > 0) {
if (start >= paragraphs.CountItems())
const int32 paragraphCount = fDocument->CountParagraphs();
if (start >= paragraphCount)
break;
const Paragraph& paragraph = paragraphs.ItemAtFast(start);
if (start >= fParagraphLayouts.CountItems()) {
const Paragraph& paragraph = fDocument->ParagraphAtIndex(start);
if (start >= static_cast<int32>(fParagraphLayouts.size())) {
ParagraphLayoutRef layout(new(std::nothrow) ParagraphLayout(
paragraph), true);
if (!layout.IsSet()
|| !fParagraphLayouts.Add(ParagraphLayoutInfo(0.0f, layout))) {
if (!layout.IsSet()) {
fprintf(stderr, "TextDocumentLayout::InvalidateParagraphs() - "
"out of memory\n");
return;
}
try {
fParagraphLayouts.push_back(ParagraphLayoutInfo(0.0f, layout));
}
catch (std::bad_alloc& ba) {
fprintf(stderr, "bad_alloc when invalidating paragraphs\n");
return;
}
} else {
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(
start);
const ParagraphLayoutInfo& info = fParagraphLayouts[start];
info.layout->SetParagraph(paragraph);
}
@ -151,8 +155,9 @@ TextDocumentLayout::InvalidateParagraphs(int32 start, int32 count)
}
// Remove any extra paragraph layouts
while (paragraphs.CountItems() < fParagraphLayouts.CountItems())
fParagraphLayouts.Remove(fParagraphLayouts.CountItems() - 1);
while (fDocument->CountParagraphs()
< static_cast<int32>(fParagraphLayouts.size()))
fParagraphLayouts.erase(fParagraphLayouts.end() - 1);
}
@ -173,8 +178,9 @@ TextDocumentLayout::Height()
float height = 0.0f;
if (fParagraphLayouts.CountItems() > 0) {
const ParagraphLayoutInfo& lastLayout = fParagraphLayouts.LastItem();
if (fParagraphLayouts.size() > 0) {
const ParagraphLayoutInfo& lastLayout
= fParagraphLayouts[fParagraphLayouts.size() - 1];
height = lastLayout.y + lastLayout.layout->Height();
}
@ -188,9 +194,9 @@ TextDocumentLayout::Draw(BView* view, const BPoint& offset,
{
_ValidateLayout();
int layoutCount = fParagraphLayouts.CountItems();
int layoutCount = fParagraphLayouts.size();
for (int i = 0; i < layoutCount; i++) {
const ParagraphLayoutInfo& layout = fParagraphLayouts.ItemAtFast(i);
const ParagraphLayoutInfo& layout = fParagraphLayouts[i];
BPoint location(offset.x, offset.y + layout.y);
if (location.y > updateRect.bottom)
break;
@ -207,10 +213,10 @@ TextDocumentLayout::LineIndexForOffset(int32 textOffset)
if (index >= 0) {
int32 lineIndex = 0;
for (int32 i = 0; i < index; i++) {
lineIndex += fParagraphLayouts.ItemAtFast(i).layout->CountLines();
lineIndex += fParagraphLayouts[i].layout->CountLines();
}
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(index);
const ParagraphLayoutInfo& info = fParagraphLayouts[index];
return lineIndex + info.layout->LineIndexForOffset(textOffset);
}
@ -224,7 +230,7 @@ TextDocumentLayout::FirstOffsetOnLine(int32 lineIndex)
int32 paragraphOffset;
int32 index = _ParagraphLayoutIndexForLineIndex(lineIndex, paragraphOffset);
if (index >= 0) {
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(index);
const ParagraphLayoutInfo& info = fParagraphLayouts[index];
return info.layout->FirstOffsetOnLine(lineIndex) + paragraphOffset;
}
@ -238,7 +244,7 @@ TextDocumentLayout::LastOffsetOnLine(int32 lineIndex)
int32 paragraphOffset;
int32 index = _ParagraphLayoutIndexForLineIndex(lineIndex, paragraphOffset);
if (index >= 0) {
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(index);
const ParagraphLayoutInfo& info = fParagraphLayouts[index];
return info.layout->LastOffsetOnLine(lineIndex) + paragraphOffset;
}
@ -253,9 +259,9 @@ TextDocumentLayout::CountLines()
int32 lineCount = 0;
int32 count = fParagraphLayouts.CountItems();
int32 count = fParagraphLayouts.size();
for (int32 i = 0; i < count; i++) {
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(i);
const ParagraphLayoutInfo& info = fParagraphLayouts[i];
lineCount += info.layout->CountLines();
}
@ -270,7 +276,7 @@ TextDocumentLayout::GetLineBounds(int32 lineIndex, float& x1, float& y1,
int32 paragraphOffset;
int32 index = _ParagraphLayoutIndexForLineIndex(lineIndex, paragraphOffset);
if (index >= 0) {
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(index);
const ParagraphLayoutInfo& info = fParagraphLayouts[index];
info.layout->GetLineBounds(lineIndex, x1, y1, x2, y2);
y1 += info.y;
y2 += info.y;
@ -290,7 +296,7 @@ TextDocumentLayout::GetTextBounds(int32 textOffset, float& x1, float& y1,
{
int32 index = _ParagraphLayoutIndexForOffset(textOffset);
if (index >= 0) {
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(index);
const ParagraphLayoutInfo& info = fParagraphLayouts[index];
info.layout->GetTextBounds(textOffset, x1, y1, x2, y2);
y1 += info.y;
y2 += info.y;
@ -312,9 +318,9 @@ TextDocumentLayout::TextOffsetAt(float x, float y, bool& rightOfCenter)
int32 textOffset = 0;
rightOfCenter = false;
int32 paragraphs = fParagraphLayouts.CountItems();
int32 paragraphs = fParagraphLayouts.size();
for (int32 i = 0; i < paragraphs; i++) {
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(i);
const ParagraphLayoutInfo& info = fParagraphLayouts[i];
if (y > info.y + info.layout->Height()) {
textOffset += info.layout->CountGlyphs();
continue;
@ -343,23 +349,28 @@ TextDocumentLayout::_ValidateLayout()
void
TextDocumentLayout::_Init()
{
fParagraphLayouts.Clear();
fParagraphLayouts.clear();
if (!fDocument.IsSet())
return;
const ParagraphList& paragraphs = fDocument->Paragraphs();
int paragraphCount = paragraphs.CountItems();
int paragraphCount = fDocument->CountParagraphs();
for (int i = 0; i < paragraphCount; i++) {
const Paragraph& paragraph = paragraphs.ItemAtFast(i);
const Paragraph& paragraph = fDocument->ParagraphAtIndex(i);
ParagraphLayoutRef layout(new(std::nothrow) ParagraphLayout(paragraph),
true);
if (!layout.IsSet()
|| !fParagraphLayouts.Add(ParagraphLayoutInfo(0.0f, layout))) {
if (!layout.IsSet()) {
fprintf(stderr, "TextDocumentLayout::_Layout() - out of memory\n");
return;
}
try {
fParagraphLayouts.push_back(ParagraphLayoutInfo(0.0f, layout));
}
catch (std::bad_alloc& ba) {
fprintf(stderr, "bad_alloc when inititalizing the text document "
"layout\n");
return;
}
}
}
@ -369,15 +380,15 @@ TextDocumentLayout::_Layout()
{
float y = 0.0f;
int layoutCount = fParagraphLayouts.CountItems();
int layoutCount = fParagraphLayouts.size();
for (int i = 0; i < layoutCount; i++) {
ParagraphLayoutInfo info = fParagraphLayouts.ItemAtFast(i);
ParagraphLayoutInfo info = fParagraphLayouts[i];
const ParagraphStyle& style = info.layout->Style();
if (i > 0)
y += style.SpacingTop();
fParagraphLayouts.Replace(i, ParagraphLayoutInfo(y, info.layout));
fParagraphLayouts[i] = ParagraphLayoutInfo(y, info.layout);
info.layout->SetWidth(fWidth);
y += info.layout->Height() + style.SpacingBottom();
@ -390,9 +401,9 @@ TextDocumentLayout::_ParagraphLayoutIndexForOffset(int32& textOffset)
{
_ValidateLayout();
int32 paragraphs = fParagraphLayouts.CountItems();
int32 paragraphs = fParagraphLayouts.size();
for (int32 i = 0; i < paragraphs - 1; i++) {
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(i);
const ParagraphLayoutInfo& info = fParagraphLayouts[i];
int32 length = info.layout->CountGlyphs();
if (textOffset >= length) {
@ -404,7 +415,8 @@ TextDocumentLayout::_ParagraphLayoutIndexForOffset(int32& textOffset)
}
if (paragraphs > 0) {
const ParagraphLayoutInfo& info = fParagraphLayouts.LastItem();
const ParagraphLayoutInfo& info
= fParagraphLayouts[fParagraphLayouts.size() - 1];
// Return last paragraph if the textOffset is still within or
// exactly behind the last valid offset in that paragraph.
@ -423,9 +435,9 @@ TextDocumentLayout::_ParagraphLayoutIndexForLineIndex(int32& lineIndex,
_ValidateLayout();
paragraphOffset = 0;
int32 paragraphs = fParagraphLayouts.CountItems();
int32 paragraphs = fParagraphLayouts.size();
for (int32 i = 0; i < paragraphs; i++) {
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(i);
const ParagraphLayoutInfo& info = fParagraphLayouts[i];
int32 lineCount = info.layout->CountLines();
if (lineIndex >= lineCount) {

View File

@ -63,9 +63,6 @@ public:
};
typedef List<ParagraphLayoutInfo, false> ParagraphLayoutList;
class TextDocumentLayout : public BReferenceable {
public:
TextDocumentLayout();
@ -125,7 +122,8 @@ private:
TextDocumentRef fDocument;
TextListenerRef fTextListener;
ParagraphLayoutList fParagraphLayouts;
std::vector<ParagraphLayoutInfo>
fParagraphLayouts;
};

View File

@ -591,9 +591,9 @@ private:
return true;
if (actions.size() != fPackageActions.size())
return true;
if (fButtons.CountItems() != actions.size())
if (fButtons.CountItems() != static_cast<int32>(actions.size()))
return true;
for (int i = 0; (i < actions.size()); i++) {
for (int i = 0; i < static_cast<int32>(actions.size()); i++) {
if (actions[i]->Type() != fPackageActions[i]->Type())
return true;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2019-2020, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2019-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -854,8 +854,8 @@ UserLoginWindow::_UnpackCaptcha(BMessage& responsePayload, Captcha& captcha)
if (result == B_OK)
result = resultMessage.FindString("pngImageDataBase64", &pngImageDataBase64);
ssize_t encodedSize;
ssize_t decodedSize;
ssize_t encodedSize = 0;
ssize_t decodedSize = 0;
if (result == B_OK) {
encodedSize = pngImageDataBase64.Length();
decodedSize = (encodedSize * 3 + 3) / 4;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2020, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2019-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -484,7 +484,6 @@ UserUsageConditionsWindow::_ExpectedIntroductionTextHeight(
float insetBottom;
introductionTextView->GetInsets(NULL, &insetTop, NULL, &insetBottom);
BSize introductionSize;
font_height fh;
be_plain_font->GetHeight(&fh);
return ((fh.ascent + fh.descent + fh.leading) * LINES_INTRODUCTION_TEXT)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017-2020, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2017-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -23,6 +23,11 @@ LoggingUrlProtocolListener::LoggingUrlProtocolListener(
}
LoggingUrlProtocolListener::~LoggingUrlProtocolListener()
{
}
void
LoggingUrlProtocolListener::BytesWritten(BUrlRequest* caller,
size_t bytesWritten)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2017-2021, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -16,6 +16,7 @@ public:
LoggingUrlProtocolListener(
BString traceLoggingIdentifier,
bool traceLogging);
virtual ~LoggingUrlProtocolListener();
size_t ContentLength();

View File

@ -13,7 +13,6 @@
#include "ValidationUtilsTest.h"
#include "StorageUtilsTest.h"
#include "TarArchiveServiceTest.h"
#include "ListTest.h"
BTestSuite*
@ -25,7 +24,6 @@ getTestSuite()
DumpExportRepositoryJsonListenerTest::AddTests(*suite);
ValidationFailureTest::AddTests(*suite);
ValidationUtilsTest::AddTests(*suite);
ListTest::AddTests(*suite);
StorageUtilsTest::AddTests(*suite);
TarArchiveServiceTest::AddTests(*suite);

View File

@ -40,8 +40,6 @@ UnitTestLib haikudepottest.so :
DumpExportRepositoryJsonListener.cpp
DumpExportRepositoryJsonListenerTest.cpp
ListTest.cpp
Logger.cpp
StandardMetaData.cpp

View File

@ -1,193 +0,0 @@
/*
* Copyright 2017-2018, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "ListTest.h"
#include <stdio.h>
#include <AutoDeleter.h>
#include <Json.h>
#include <cppunit/TestCaller.h>
#include <cppunit/TestSuite.h>
#include "List.h"
ListTest::ListTest()
{
}
ListTest::~ListTest()
{
}
static int32 CompareStrings(const BString& a, const BString& b)
{
return a.Compare(b);
}
static int32 CompareWithContextString(const void* context, const BString& str)
{
const char* contextString = static_cast<const char*>(context);
return -1 * str.Compare(contextString);
}
/*! This tests the insertion of various letters into the list and the subsequent
search for those values later using a binary search.
*/
void
ListTest::TestBinarySearch()
{
List<BString, false> list(&CompareStrings, &CompareWithContextString);
BString tmp;
for(char c = 'a'; c <= 'z'; c++) {
tmp.SetToFormat("%c", c);
list.Add(tmp);
}
// ----------------------
int32 aIndex = list.Search("a");
int32 hIndex = list.Search("h");
int32 uIndex = list.Search("u");
int32 zIndex = list.Search("z");
int32 ampersandIndex = list.Search("&");
// ----------------------
CPPUNIT_ASSERT_EQUAL(0, aIndex);
CPPUNIT_ASSERT_EQUAL(7, hIndex);
CPPUNIT_ASSERT_EQUAL(20, uIndex);
CPPUNIT_ASSERT_EQUAL(25, zIndex);
CPPUNIT_ASSERT_EQUAL(-1, ampersandIndex);
}
/*! In this test, a number of letters are added into a list. Later a check is
made to ensure that the letters were added in order.
*/
void
ListTest::TestAddOrdered()
{
List<BString, false> list(&CompareStrings, NULL);
// ----------------------
list.Add(BString("p")); //1
list.Add(BString("o"));
list.Add(BString("n"));
list.Add(BString("s"));
list.Add(BString("b")); //5
list.Add(BString("y"));
list.Add(BString("r"));
list.Add(BString("d"));
list.Add(BString("i"));
list.Add(BString("k")); //10
list.Add(BString("t"));
list.Add(BString("e"));
list.Add(BString("a"));
list.Add(BString("u"));
list.Add(BString("z")); // 15
list.Add(BString("q"));
// ----------------------
CPPUNIT_ASSERT_EQUAL_MESSAGE("expected count of package infos",
16, list.CountItems());
CPPUNIT_ASSERT_EQUAL(BString("a"), list.ItemAt(0));
CPPUNIT_ASSERT_EQUAL(BString("b"), list.ItemAt(1));
CPPUNIT_ASSERT_EQUAL(BString("d"), list.ItemAt(2));
CPPUNIT_ASSERT_EQUAL(BString("e"), list.ItemAt(3));
CPPUNIT_ASSERT_EQUAL(BString("i"), list.ItemAt(4));
CPPUNIT_ASSERT_EQUAL(BString("k"), list.ItemAt(5));
CPPUNIT_ASSERT_EQUAL(BString("n"), list.ItemAt(6));
CPPUNIT_ASSERT_EQUAL(BString("o"), list.ItemAt(7));
CPPUNIT_ASSERT_EQUAL(BString("p"), list.ItemAt(8));
CPPUNIT_ASSERT_EQUAL(BString("q"), list.ItemAt(9));
CPPUNIT_ASSERT_EQUAL(BString("r"), list.ItemAt(10));
CPPUNIT_ASSERT_EQUAL(BString("s"), list.ItemAt(11));
CPPUNIT_ASSERT_EQUAL(BString("t"), list.ItemAt(12));
CPPUNIT_ASSERT_EQUAL(BString("u"), list.ItemAt(13));
CPPUNIT_ASSERT_EQUAL(BString("y"), list.ItemAt(14));
CPPUNIT_ASSERT_EQUAL(BString("z"), list.ItemAt(15));
}
/*! This test will add a number of letters to a list which has no ordering. The
letters should then appear in the list in the order of insertion.
*/
void
ListTest::TestAddUnordered()
{
List<BString, false> list;
// ----------------------
list.Add(BString("b"));
list.Add(BString("e"));
list.Add(BString("t"));
list.Add(BString("h"));
list.Add(BString("e"));
list.Add(BString("l"));
list.Add(BString("l"));
list.Add(BString("s"));
list.Add(BString("b"));
list.Add(BString("e"));
list.Add(BString("a"));
list.Add(BString("c"));
list.Add(BString("h"));
// ----------------------
CPPUNIT_ASSERT_EQUAL_MESSAGE("expected count of package infos",
13, list.CountItems());
CPPUNIT_ASSERT_EQUAL(BString("b"), list.ItemAt(0));
CPPUNIT_ASSERT_EQUAL(BString("e"), list.ItemAt(1));
CPPUNIT_ASSERT_EQUAL(BString("t"), list.ItemAt(2));
CPPUNIT_ASSERT_EQUAL(BString("h"), list.ItemAt(3));
CPPUNIT_ASSERT_EQUAL(BString("e"), list.ItemAt(4));
CPPUNIT_ASSERT_EQUAL(BString("l"), list.ItemAt(5));
CPPUNIT_ASSERT_EQUAL(BString("l"), list.ItemAt(6));
CPPUNIT_ASSERT_EQUAL(BString("s"), list.ItemAt(7));
CPPUNIT_ASSERT_EQUAL(BString("b"), list.ItemAt(8));
CPPUNIT_ASSERT_EQUAL(BString("e"), list.ItemAt(9));
CPPUNIT_ASSERT_EQUAL(BString("a"), list.ItemAt(10));
CPPUNIT_ASSERT_EQUAL(BString("c"), list.ItemAt(11));
CPPUNIT_ASSERT_EQUAL(BString("h"), list.ItemAt(12));
}
/*static*/ void
ListTest::AddTests(BTestSuite& parent)
{
CppUnit::TestSuite& suite = *new CppUnit::TestSuite(
"ListTest");
suite.addTest(
new CppUnit::TestCaller<ListTest>(
"ListTest::TestAddOrdered",
&ListTest::TestAddOrdered));
suite.addTest(
new CppUnit::TestCaller<ListTest>(
"ListTest::TestBinarySearch",
&ListTest::TestBinarySearch));
suite.addTest(
new CppUnit::TestCaller<ListTest>(
"ListTest::TestAddUnordered",
&ListTest::TestAddUnordered));
parent.addTest("ListTest", &suite);
}

View File

@ -1,26 +0,0 @@
/*
* Copyright 2017-2018, Andrew Lindesay <apl@lindesay.co.nz>
* Distributed under the terms of the MIT License.
*/
#ifndef LIST_TEST_H
#define LIST_TEST_H
#include <TestCase.h>
#include <TestSuite.h>
class ListTest : public CppUnit::TestCase {
public:
ListTest();
virtual ~ListTest();
void TestAddOrdered();
void TestBinarySearch();
void TestAddUnordered();
static void AddTests(BTestSuite& suite);
};
#endif // LIST_TEST_H