summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2013-04-22 21:24:52 +0300
committerAndrei Karas <akaras@inbox.ru>2013-04-25 16:35:59 +0300
commit0d300e7aa5699154810af67282dacbcd65929768 (patch)
treee84bcce0aebdfeaf8ead8ee936851548883fc57e
parentcf3ee45291930bec0b10d9bd4b5b525e6e2b395d (diff)
downloadmv-0d300e7aa5699154810af67282dacbcd65929768.tar.gz
mv-0d300e7aa5699154810af67282dacbcd65929768.tar.bz2
mv-0d300e7aa5699154810af67282dacbcd65929768.tar.xz
mv-0d300e7aa5699154810af67282dacbcd65929768.zip
impliment new list in sdlfont.
-rw-r--r--src/Makefile.am1
-rw-r--r--src/commands.cpp8
-rw-r--r--src/gui/sdlfont.cpp381
-rw-r--r--src/gui/sdlfont.h54
-rw-r--r--src/gui/sdlfont_unittest.cc304
5 files changed, 599 insertions, 149 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 38b37afe1..d4b994988 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -828,6 +828,7 @@ manaplus_SOURCES += \
if ENABLE_UNITTESTS
manaplus_CXXFLAGS += -DUNITTESTS
manaplus_SOURCES += \
+ gui/sdlfont_unittest.cc \
gui/widgets/browserbox_unittest.cc \
utils/stringutils_unittest.cc
endif
diff --git a/src/commands.cpp b/src/commands.cpp
index 065983a01..8f03780ba 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -920,11 +920,12 @@ impHandler0(cacheInfo)
if (!chatWindow || !debugChatTab)
return;
+/*
SDLFont *const font = dynamic_cast<SDLFont *const>(chatWindow->getFont());
if (!font)
return;
- const std::list<SDLTextChunk> *const cache = font->getCache();
+ const TextChunkList *const cache = font->getCache();
if (!cache)
return;
@@ -933,9 +934,9 @@ impHandler0(cacheInfo)
std::string str;
for (int f = 0; f < 256; f ++)
{
- if (!cache[f].empty())
+ if (!cache[f].size)
{
- const unsigned int sz = static_cast<int>(cache[f].size());
+ const unsigned int sz = static_cast<int>(cache[f].size);
all += sz;
str.append(strprintf("%d: %u, ", f, sz));
}
@@ -949,6 +950,7 @@ impHandler0(cacheInfo)
debugChatTab->chatLog(strprintf("%s %d",
_("Deleted:"), font->getDeleteCounter()));
#endif
+*/
}
impHandler0(serverIgnoreAll)
diff --git a/src/gui/sdlfont.cpp b/src/gui/sdlfont.cpp
index 1acb50720..8ffb14b13 100644
--- a/src/gui/sdlfont.cpp
+++ b/src/gui/sdlfont.cpp
@@ -46,116 +46,220 @@ const int OUTLINE_SIZE = 1;
char *strBuf;
-class SDLTextChunk final
+const unsigned int CACHES_NUMBER = 256;
+
+#ifdef UNITTESTS
+int sdlTextChunkCnt = 0;
+#endif
+
+SDLTextChunk::SDLTextChunk(const std::string &text0, const gcn::Color &color0,
+ const gcn::Color &color1) :
+ img(nullptr),
+ text(text0),
+ color(color0),
+ color2(color1),
+ next(nullptr)
{
- public:
- SDLTextChunk(const std::string &text0, const gcn::Color &color0,
- const gcn::Color &color1) :
- img(nullptr), text(text0), color(color0), color2(color1)
- {
- }
+#ifdef UNITTESTS
+ sdlTextChunkCnt ++;
+#endif
+}
+SDLTextChunk::~SDLTextChunk()
+{
+ delete img;
+ img = nullptr;
+#ifdef UNITTESTS
+ sdlTextChunkCnt --;
+#endif
+}
- ~SDLTextChunk()
+bool SDLTextChunk::operator==(const SDLTextChunk &chunk) const
+{
+ return (chunk.text == text && chunk.color == color
+ && chunk.color2 == color2);
+}
+
+void SDLTextChunk::generate(TTF_Font *const font, const float alpha)
+{
+ BLOCK_START("SDLTextChunk::generate")
+ SDL_Color sdlCol;
+ sdlCol.b = static_cast<uint8_t>(color.b);
+ sdlCol.r = static_cast<uint8_t>(color.r);
+ sdlCol.g = static_cast<uint8_t>(color.g);
+ sdlCol.unused = 0;
+
+ getSafeUtf8String(text, strBuf);
+
+ SDL_Surface *surface = TTF_RenderUTF8_Blended(
+ font, strBuf, sdlCol);
+
+ if (!surface)
+ {
+ img = nullptr;
+ BLOCK_END("SDLTextChunk::generate")
+ return;
+ }
+
+ const int width = surface->w;
+ const int height = surface->h;
+
+ if (color.r != color2.r || color.g != color2.g
+ || color.b != color2.b)
+ { // outlining
+ SDL_Color sdlCol2;
+ SDL_Surface *background = imageHelper->create32BitSurface(
+ width, height);
+ if (!background)
{
- delete img;
img = nullptr;
+ SDL_FreeSurface(surface);
+ BLOCK_END("SDLTextChunk::generate")
+ return;
}
-
- bool operator==(const SDLTextChunk &chunk) const
+ sdlCol2.b = static_cast<uint8_t>(color2.b);
+ sdlCol2.r = static_cast<uint8_t>(color2.r);
+ sdlCol2.g = static_cast<uint8_t>(color2.g);
+ sdlCol2.unused = 0;
+ SDL_Surface *const surface2 = TTF_RenderUTF8_Blended(
+ font, strBuf, sdlCol2);
+ if (!surface2)
{
- return (chunk.text == text && chunk.color == color
- && chunk.color2 == color2);
+ img = nullptr;
+ SDL_FreeSurface(surface);
+ BLOCK_END("SDLTextChunk::generate")
+ return;
}
-
- void generate(TTF_Font *const font, const float alpha)
+ SDL_Rect rect =
{
- BLOCK_START("SDLTextChunk::generate")
- SDL_Color sdlCol;
- sdlCol.b = static_cast<uint8_t>(color.b);
- sdlCol.r = static_cast<uint8_t>(color.r);
- sdlCol.g = static_cast<uint8_t>(color.g);
- sdlCol.unused = 0;
-
- getSafeUtf8String(text, strBuf);
-
- SDL_Surface *surface = TTF_RenderUTF8_Blended(
- font, strBuf, sdlCol);
-
- if (!surface)
- {
- img = nullptr;
- BLOCK_END("SDLTextChunk::generate")
- return;
- }
-
- const int width = surface->w;
- const int height = surface->h;
-
- if (color.r != color2.r || color.g != color2.g
- || color.b != color2.b)
- { // outlining
- SDL_Color sdlCol2;
- SDL_Surface *background = imageHelper->create32BitSurface(
- width, height);
- if (!background)
- {
- img = nullptr;
- SDL_FreeSurface(surface);
- BLOCK_END("SDLTextChunk::generate")
- return;
- }
- sdlCol2.b = static_cast<uint8_t>(color2.b);
- sdlCol2.r = static_cast<uint8_t>(color2.r);
- sdlCol2.g = static_cast<uint8_t>(color2.g);
- sdlCol2.unused = 0;
- SDL_Surface *const surface2 = TTF_RenderUTF8_Blended(
- font, strBuf, sdlCol2);
- if (!surface2)
- {
- img = nullptr;
- SDL_FreeSurface(surface);
- BLOCK_END("SDLTextChunk::generate")
- return;
- }
- SDL_Rect rect =
- {
- OUTLINE_SIZE,
- 0,
- static_cast<Uint16>(surface->w),
- static_cast<Uint16>(surface->h)
- };
+ OUTLINE_SIZE,
+ 0,
+ static_cast<Uint16>(surface->w),
+ static_cast<Uint16>(surface->h)
+ };
// SDL_SetAlpha(surface2, 0, SDL_ALPHA_OPAQUE);
- MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect);
- rect.x = -OUTLINE_SIZE;
- MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect);
- rect.x = 0;
- rect.y = -OUTLINE_SIZE;
- MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect);
- rect.y = OUTLINE_SIZE;
- MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect);
- rect.x = 0;
- rect.y = 0;
+ MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect);
+ rect.x = -OUTLINE_SIZE;
+ MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect);
+ rect.x = 0;
+ rect.y = -OUTLINE_SIZE;
+ MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect);
+ rect.y = OUTLINE_SIZE;
+ MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect);
+ rect.x = 0;
+ rect.y = 0;
// SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE);
- MSDL_gfxBlitRGBA(surface, nullptr, background, &rect);
- SDL_FreeSurface(surface);
- SDL_FreeSurface(surface2);
- surface = background;
- }
- img = imageHelper->createTextSurface(
- surface, width, height, alpha);
- SDL_FreeSurface(surface);
+ MSDL_gfxBlitRGBA(surface, nullptr, background, &rect);
+ SDL_FreeSurface(surface);
+ SDL_FreeSurface(surface2);
+ surface = background;
+ }
+ img = imageHelper->createTextSurface(
+ surface, width, height, alpha);
+ SDL_FreeSurface(surface);
+
+ BLOCK_END("SDLTextChunk::generate")
+}
- BLOCK_END("SDLTextChunk::generate")
- }
- Image *img;
- std::string text;
- gcn::Color color;
- gcn::Color color2;
-};
+TextChunkList::TextChunkList() :
+ start(nullptr),
+ end(nullptr),
+ size(0)
+{
+}
-typedef std::list<SDLTextChunk>::iterator CacheIterator;
+void TextChunkList::insertFirst(SDLTextChunk *const item)
+{
+ SDLTextChunk *const oldFirst = start;
+ if (start)
+ start->prev = item;
+ item->prev = nullptr;
+ if (oldFirst)
+ item->next = oldFirst;
+ else
+ end = item;
+ start = item;
+ size ++;
+}
+
+void TextChunkList::moveToFirst(SDLTextChunk *item)
+{
+ if (item == start)
+ return;
+
+ SDLTextChunk *oldPrev = item->prev;
+ if (oldPrev)
+ oldPrev->next = item->next;
+ SDLTextChunk *oldNext = item->next;
+ if (oldNext)
+ oldNext->prev = item->prev;
+ else
+ end = oldPrev;
+ SDLTextChunk *const oldFirst = start;
+ if (start)
+ start->prev = item;
+ item->prev = nullptr;
+ item->next = oldFirst;
+ start = item;
+}
+
+void TextChunkList::removeBack()
+{
+ SDLTextChunk *oldEnd = end;
+ if (oldEnd)
+ {
+ end = oldEnd->prev;
+ if (end)
+ end->next = nullptr;
+ else
+ start = nullptr;
+ delete oldEnd;
+ size --;
+ }
+}
+
+void TextChunkList::removeBack(int n)
+{
+ SDLTextChunk *item = end;
+ while (n && item)
+ {
+ n --;
+ SDLTextChunk *oldEnd = item;
+ item = item->prev;
+ delete oldEnd;
+ size --;
+ }
+ if (item)
+ {
+ item->next = nullptr;
+ end = item;
+ }
+ else
+ {
+ start = nullptr;
+ end = nullptr;
+ }
+}
+
+void TextChunkList::clear()
+{
+ SDLTextChunk *item = start;
+ while (item)
+ {
+ SDLTextChunk *item2 = item->next;
+ delete item;
+ item = item2;
+ }
+ start = nullptr;
+ end = nullptr;
+ size = 0;
+}
+
+namespace
+{
+ TextChunkList mCache[CACHES_NUMBER];
+} // namespace
static int fontCounter;
@@ -205,6 +309,7 @@ SDLFont::~SDLFont()
TTF_CloseFont(mFont);
mFont = nullptr;
--fontCounter;
+ clear();
if (fontCounter == 0)
{
@@ -246,9 +351,7 @@ void SDLFont::loadFont(std::string filename, const int size, const int style)
void SDLFont::clear()
{
for (size_t f = 0; f < CACHES_NUMBER; f ++)
- {
mCache[f].clear();
- }
}
void SDLFont::drawString(gcn::Graphics *const graphics,
@@ -278,7 +381,7 @@ void SDLFont::drawString(gcn::Graphics *const graphics,
SDLTextChunk chunk(text, col, col2);
const unsigned char chr = text[0];
- std::list<SDLTextChunk> *const cache = &mCache[chr];
+ TextChunkList *const cache = &mCache[chr];
bool found = false;
@@ -286,19 +389,22 @@ void SDLFont::drawString(gcn::Graphics *const graphics,
int cnt = 0;
#endif
- FOR_EACHP (CacheIterator, i, cache)
+ SDLTextChunk *i = cache->start;
+ while (i)
{
- if (chunk == (*i))
+ if (*i == chunk)
{
// Raise priority: move it to front
- cache->splice(cache->begin(), *cache, i);
+ cache->moveToFirst(i);
found = true;
break;
}
+ i = i->next;
#ifdef DEBUG_FONT
cnt ++;
#endif
}
+
#ifdef DEBUG_FONT
logger->log(std::string("drawString: ").append(text).append(
", iterations: ").append(toString(cnt)));
@@ -307,28 +413,33 @@ void SDLFont::drawString(gcn::Graphics *const graphics,
// Surface not found
if (!found)
{
- if (cache->size() >= CACHE_SIZE)
+ if (cache->size >= CACHE_SIZE)
{
#ifdef DEBUG_FONT_COUNTERS
mDeleteCounter ++;
#endif
- cache->pop_back();
+ cache->removeBack();
}
#ifdef DEBUG_FONT_COUNTERS
mCreateCounter ++;
#endif
- cache->push_front(chunk);
- SDLTextChunk &data = cache->front();
- data.generate(mFont, alpha);
+ SDLTextChunk *chunk2 = new SDLTextChunk(text, col, col2);
+
+ chunk2->generate(mFont, alpha);
+ cache->insertFirst(chunk2);
- if (data.img)
- g->drawImage(data.img, x, y);
+ const Image *const image = chunk2->img;
+ if (image)
+ g->drawImage(image, x, y);
}
- else if (cache->front().img)
+ else
{
- Image *const image = cache->front().img;
- image->setAlpha(alpha);
- g->drawImage(image, x, y);
+ Image *const image = cache->start->img;
+ if (image)
+ {
+ image->setAlpha(alpha);
+ g->drawImage(image, x, y);
+ }
}
BLOCK_END("SDLFont::drawString")
}
@@ -348,40 +459,33 @@ void SDLFont::slowLogic(const int rnd)
BLOCK_END("SDLFont::slowLogic")
}
-void SDLFont::createSDLTextChunk(SDLTextChunk *const chunk)
-{
- if (!chunk || chunk->text.empty())
- return;
-
- const float alpha = static_cast<float>(chunk->color.a) / 255.0f;
- chunk->color.a = 255;
- chunk->generate(mFont, alpha);
-}
-
int SDLFont::getWidth(const std::string &text) const
{
if (text.empty())
return 0;
const unsigned char chr = text[0];
- std::list<SDLTextChunk> *const cache = &mCache[chr];
+ TextChunkList *const cache = &mCache[chr];
#ifdef DEBUG_FONT
int cnt = 0;
#endif
- FOR_EACHP (CacheIterator, i, cache)
+ SDLTextChunk *i = cache->start;
+ while (i)
{
if (i->text == text)
{
// Raise priority: move it to front
// Assumption is that TTF::draw will be called next
- cache->splice(cache->begin(), *cache, i);
- if (i->img)
- return i->img->getWidth();
+ cache->moveToFirst(i);
+ const Image *const image = i->img;
+ if (image)
+ return image->getWidth();
else
return 0;
}
+ i = i->next;
#ifdef DEBUG_FONT
cnt ++;
#endif
@@ -407,8 +511,8 @@ void SDLFont::doClean()
{
for (unsigned int f = 0; f < CACHES_NUMBER; f ++)
{
- std::list<SDLTextChunk> *const cache = &mCache[f];
- const size_t size = cache->size();
+ TextChunkList *const cache = &mCache[f];
+ const size_t size = cache->size;
#ifdef DEBUG_FONT_COUNTERS
logger->log("ptr: %d, size: %d", f, size);
#endif
@@ -417,10 +521,7 @@ void SDLFont::doClean()
#ifdef DEBUG_FONT_COUNTERS
mDeleteCounter += 100;
#endif
- const std::list<SDLTextChunk>::iterator it_end = cache->end();
- std::list<SDLTextChunk>::iterator it = cache->begin();
- std::advance(it, -100);
- cache->erase(it, it_end);
+ cache->removeBack(100);
#ifdef DEBUG_FONT_COUNTERS
logger->log("delete3");
#endif
@@ -430,10 +531,7 @@ void SDLFont::doClean()
#ifdef DEBUG_FONT_COUNTERS
mDeleteCounter += 20;
#endif
- const std::list<SDLTextChunk>::iterator it_end = cache->end();
- std::list<SDLTextChunk>::iterator it = cache->begin();
- std::advance(it, -20);
- cache->erase(it, it_end);
+ cache->removeBack(20);
#ifdef DEBUG_FONT_COUNTERS
logger->log("delete2");
#endif
@@ -443,10 +541,15 @@ void SDLFont::doClean()
#ifdef DEBUG_FONT_COUNTERS
mDeleteCounter ++;
#endif
- cache->pop_back();
+ cache->removeBack();
#ifdef DEBUG_FONT_COUNTERS
logger->log("delete1");
#endif
}
}
}
+
+TextChunkList *SDLFont::getCache()
+{
+ return mCache;
+}
diff --git a/src/gui/sdlfont.h b/src/gui/sdlfont.h
index 4e77943f8..2e5376148 100644
--- a/src/gui/sdlfont.h
+++ b/src/gui/sdlfont.h
@@ -24,6 +24,7 @@
#ifndef SDLFONT_H
#define SDLFONT_H
+#include <guichan/color.hpp>
#include <guichan/font.hpp>
#ifdef __WIN32__
@@ -37,9 +38,48 @@
#include "localconsts.h"
-const unsigned int CACHES_NUMBER = 256;
+class Image;
-class SDLTextChunk;
+class SDLTextChunk final
+{
+ public:
+ SDLTextChunk(const std::string &text0, const gcn::Color &color0,
+ const gcn::Color &color1);
+
+ ~SDLTextChunk();
+
+ bool operator==(const SDLTextChunk &chunk) const;
+
+ void generate(TTF_Font *const font, const float alpha);
+
+ Image *img;
+ std::string text;
+ gcn::Color color;
+ gcn::Color color2;
+ SDLTextChunk *prev;
+ SDLTextChunk *next;
+};
+
+
+class TextChunkList final
+{
+ public:
+ TextChunkList();
+
+ void insertFirst(SDLTextChunk *const item);
+
+ void moveToFirst(SDLTextChunk *item);
+
+ void removeBack();
+
+ void removeBack(int n);
+
+ void clear();
+
+ SDLTextChunk *start;
+ SDLTextChunk *end;
+ uint32_t size;
+};
/**
* A wrapper around SDL_ttf for allowing the use of TrueType fonts.
@@ -67,14 +107,11 @@ class SDLFont final : public gcn::Font
void loadFont(std::string filename, const int size,
const int style = 0);
- void createSDLTextChunk(SDLTextChunk *const chunk);
-
virtual int getWidth(const std::string &text) const A_WARN_UNUSED;
virtual int getHeight() const A_WARN_UNUSED;
- std::list<SDLTextChunk> *getCache() A_WARN_UNUSED
- { return mCache; }
+ TextChunkList *getCache() A_WARN_UNUSED;
/**
* @see Font::drawString
@@ -101,8 +138,11 @@ class SDLFont final : public gcn::Font
unsigned mDeleteCounter;
// Word surfaces cache
- mutable std::list<SDLTextChunk> mCache[CACHES_NUMBER];
int mCleanTime;
};
+#ifdef UNITTESTS
+extern int sdlTextChunkCnt;
+#endif
+
#endif
diff --git a/src/gui/sdlfont_unittest.cc b/src/gui/sdlfont_unittest.cc
new file mode 100644
index 000000000..31b76f131
--- /dev/null
+++ b/src/gui/sdlfont_unittest.cc
@@ -0,0 +1,304 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "logger.h"
+
+#include "gui/sdlfont.h"
+#include "gui/theme.h"
+
+#include "gtest/gtest.h"
+
+#include "debug.h"
+
+TEST(TextChunkList, empty)
+{
+ TextChunkList list;
+
+ EXPECT_EQ(0, list.size);
+ EXPECT_EQ(nullptr, list.start);
+ EXPECT_EQ(nullptr, list.end);
+}
+
+TEST(TextChunkList, add1)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk);
+
+ EXPECT_EQ(1, list.size);
+ EXPECT_EQ(chunk, list.start);
+ EXPECT_EQ(chunk, list.end);
+ EXPECT_EQ(nullptr, chunk->prev);
+ EXPECT_EQ(nullptr, chunk->next);
+}
+
+TEST(TextChunkList, add2)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk1);
+
+ EXPECT_EQ(2, list.size);
+ EXPECT_EQ(chunk1, list.start);
+ EXPECT_EQ(chunk2, list.end);
+ EXPECT_EQ(nullptr, chunk1->prev);
+ EXPECT_EQ(chunk2, chunk1->next);
+ EXPECT_EQ(chunk1, chunk2->prev);
+ EXPECT_EQ(nullptr, chunk2->next);
+}
+
+TEST(TextChunkList, addRemoveBack1)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk);
+ list.removeBack();
+
+ EXPECT_EQ(0, list.size);
+ EXPECT_EQ(nullptr, list.start);
+ EXPECT_EQ(nullptr, list.end);
+}
+
+TEST(TextChunkList, addRemoveBack2)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk1);
+ list.removeBack();
+
+ EXPECT_EQ(1, list.size);
+ EXPECT_EQ(chunk1, list.start);
+ EXPECT_EQ(chunk1, list.end);
+ EXPECT_EQ(nullptr, chunk1->prev);
+ EXPECT_EQ(nullptr, chunk1->next);
+}
+
+TEST(TextChunkList, addRemoveBack3)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk1);
+ list.removeBack(2);
+
+ EXPECT_EQ(0, list.size);
+ EXPECT_EQ(nullptr, list.start);
+ EXPECT_EQ(nullptr, list.end);
+}
+
+TEST(TextChunkList, addRemoveBack4)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk3);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk1);
+ list.removeBack();
+ list.removeBack();
+
+ EXPECT_EQ(1, list.size);
+ EXPECT_EQ(chunk1, list.start);
+ EXPECT_EQ(chunk1, list.end);
+ EXPECT_EQ(nullptr, chunk1->prev);
+ EXPECT_EQ(nullptr, chunk1->next);
+}
+
+TEST(TextChunkList, moveToFirst1)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk);
+ list.moveToFirst(chunk);
+
+ EXPECT_EQ(1, list.size);
+ EXPECT_EQ(chunk, list.start);
+ EXPECT_EQ(chunk, list.end);
+ EXPECT_EQ(nullptr, chunk->prev);
+ EXPECT_EQ(nullptr, chunk->next);
+}
+
+TEST(TextChunkList, moveToFirst2)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.moveToFirst(chunk1);
+
+ EXPECT_EQ(2, list.size);
+ EXPECT_EQ(chunk1, list.start);
+ EXPECT_EQ(chunk2, list.end);
+ EXPECT_EQ(nullptr, chunk1->prev);
+ EXPECT_EQ(chunk2, chunk1->next);
+ EXPECT_EQ(chunk1, chunk2->prev);
+ EXPECT_EQ(nullptr, chunk2->next);
+}
+
+TEST(TextChunkList, moveToFirst3)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk3);
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.moveToFirst(chunk1);
+
+ EXPECT_EQ(3, list.size);
+ EXPECT_EQ(chunk1, list.start);
+ EXPECT_EQ(chunk3, list.end);
+ EXPECT_EQ(nullptr, chunk1->prev);
+ EXPECT_EQ(chunk2, chunk1->next);
+ EXPECT_EQ(chunk1, chunk2->prev);
+ EXPECT_EQ(chunk3, chunk2->next);
+ EXPECT_EQ(chunk2, chunk3->prev);
+ EXPECT_EQ(nullptr, chunk3->next);
+}
+
+TEST(TextChunkList, moveToFirst4)
+{
+ TextChunkList list;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk3);
+ list.insertFirst(chunk2);
+ list.moveToFirst(chunk1);
+
+ EXPECT_EQ(3, list.size);
+ EXPECT_EQ(chunk1, list.start);
+ EXPECT_EQ(chunk3, list.end);
+ EXPECT_EQ(nullptr, chunk1->prev);
+ EXPECT_EQ(chunk2, chunk1->next);
+ EXPECT_EQ(chunk1, chunk2->prev);
+ EXPECT_EQ(chunk3, chunk2->next);
+ EXPECT_EQ(chunk2, chunk3->prev);
+ EXPECT_EQ(nullptr, chunk3->next);
+}
+
+TEST(TextChunkList, clear1)
+{
+ TextChunkList list;
+ int chunksLeft = sdlTextChunkCnt;
+
+ SDLTextChunk *chunk = new SDLTextChunk("test", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk);
+ list.clear();
+
+ EXPECT_EQ(0, list.size);
+ EXPECT_EQ(nullptr, list.start);
+ EXPECT_EQ(nullptr, list.end);
+ EXPECT_EQ(chunksLeft, sdlTextChunkCnt);
+}
+
+TEST(TextChunkList, clear2)
+{
+ TextChunkList list;
+ int chunksLeft = sdlTextChunkCnt;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test1", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk3);
+ list.clear();
+
+ EXPECT_EQ(0, list.size);
+ EXPECT_EQ(nullptr, list.start);
+ EXPECT_EQ(nullptr, list.end);
+ EXPECT_EQ(chunksLeft, sdlTextChunkCnt);
+}
+
+TEST(TextChunkList, clear3)
+{
+ TextChunkList list;
+ int chunksLeft = sdlTextChunkCnt;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test1", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk3);
+ list.moveToFirst(chunk1);
+ EXPECT_EQ(chunksLeft + 3, sdlTextChunkCnt);
+
+ list.removeBack();
+ EXPECT_EQ(chunksLeft + 2, sdlTextChunkCnt);
+
+ list.clear();
+ EXPECT_EQ(chunksLeft, sdlTextChunkCnt);
+}
+
+TEST(TextChunkList, clear4)
+{
+ TextChunkList list;
+ int chunksLeft = sdlTextChunkCnt;
+
+ SDLTextChunk *chunk1 = new SDLTextChunk("test1", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color());
+ SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color());
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk3);
+ list.moveToFirst(chunk2);
+ EXPECT_EQ(chunksLeft + 3, sdlTextChunkCnt);
+
+ list.removeBack(2);
+ EXPECT_EQ(chunksLeft + 1, sdlTextChunkCnt);
+
+ list.clear();
+ EXPECT_EQ(chunksLeft, sdlTextChunkCnt);
+}