summaryrefslogtreecommitdiff
path: root/src/ftgl/FTLayout
diff options
context:
space:
mode:
Diffstat (limited to 'src/ftgl/FTLayout')
-rw-r--r--src/ftgl/FTLayout/FTLayout.cpp80
-rw-r--r--src/ftgl/FTLayout/FTLayoutGlue.cpp171
-rw-r--r--src/ftgl/FTLayout/FTLayoutImpl.h56
-rw-r--r--src/ftgl/FTLayout/FTSimpleLayout.cpp460
-rw-r--r--src/ftgl/FTLayout/FTSimpleLayoutImpl.h225
5 files changed, 992 insertions, 0 deletions
diff --git a/src/ftgl/FTLayout/FTLayout.cpp b/src/ftgl/FTLayout/FTLayout.cpp
new file mode 100644
index 0000000..d4298bd
--- /dev/null
+++ b/src/ftgl/FTLayout/FTLayout.cpp
@@ -0,0 +1,80 @@
+/*
+ * FTGL - OpenGL font library
+ *
+ * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
+ * Copyright (c) 2008 Sam Hocevar <sam@zoy.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include "FTGL/ftgl.h"
+
+#include "../FTFont/FTFontImpl.h"
+#include "./FTLayoutImpl.h"
+
+
+//
+// FTLayout
+//
+
+
+FTLayout::FTLayout()
+{
+ impl = new FTLayoutImpl();
+}
+
+
+FTLayout::FTLayout(FTLayoutImpl *pImpl)
+{
+ impl = pImpl;
+}
+
+
+FTLayout::~FTLayout()
+{
+ delete impl;
+}
+
+
+FT_Error FTLayout::Error() const
+{
+ return impl->err;
+}
+
+
+//
+// FTLayoutImpl
+//
+
+
+FTLayoutImpl::FTLayoutImpl() :
+ err(0)
+{
+ ;
+}
+
+
+FTLayoutImpl::~FTLayoutImpl()
+{
+ ;
+}
+
diff --git a/src/ftgl/FTLayout/FTLayoutGlue.cpp b/src/ftgl/FTLayout/FTLayoutGlue.cpp
new file mode 100644
index 0000000..60f428d
--- /dev/null
+++ b/src/ftgl/FTLayout/FTLayoutGlue.cpp
@@ -0,0 +1,171 @@
+/*
+ * FTGL - OpenGL font library
+ *
+ * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
+ * Copyright (c) 2008 Éric Beets <ericbeets@free.fr>
+ * Copyright (c) 2008 Sam Hocevar <sam@zoy.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include "FTInternals.h"
+
+static const FTBBox static_ftbbox;
+
+FTGL_BEGIN_C_DECLS
+
+#define C_TOR(cname, cargs, cxxname, cxxarg, cxxtype) \
+ FTGLlayout* cname cargs \
+ { \
+ cxxname *l = new cxxname cxxarg; \
+ if(l->Error()) \
+ { \
+ delete l; \
+ return NULL; \
+ } \
+ FTGLlayout *ftgl = (FTGLlayout *)malloc(sizeof(FTGLlayout)); \
+ ftgl->ptr = l; \
+ ftgl->type = cxxtype; \
+ return ftgl; \
+ }
+
+// FTSimpleLayout::FTSimpleLayout();
+C_TOR(ftglCreateSimpleLayout, (), FTSimpleLayout, (), LAYOUT_SIMPLE);
+
+#define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \
+ cret cname cargs \
+ { \
+ if(!l || !l->ptr) \
+ { \
+ fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \
+ cxxerr; \
+ } \
+ return l->ptr->cxxname cxxarg; \
+ }
+
+// FTLayout::~FTLayout();
+void ftglDestroyLayout(FTGLlayout *l)
+{
+ if(!l || !l->ptr)
+ {
+ fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__);
+ return;
+ }
+ delete l->ptr;
+ free(l);
+}
+
+// virtual FTBBox FTLayout::BBox(const char* string)
+extern "C++" {
+C_FUN(static FTBBox, _ftgGetlLayoutBBox, (FTGLlayout *l, const char *s),
+ return static_ftbbox, BBox, (s));
+}
+
+void ftgGetlLayoutBBox(FTGLlayout *l, const char * s, float c[6])
+{
+ FTBBox ret = _ftgGetlLayoutBBox(l, s);
+ FTPoint lower = ret.Lower(), upper = ret.Upper();
+ c[0] = lower.Xf(); c[1] = lower.Yf(); c[2] = lower.Zf();
+ c[3] = upper.Xf(); c[4] = upper.Yf(); c[5] = upper.Zf();
+}
+
+// virtual void FTLayout::Render(const char* string, int renderMode);
+C_FUN(void, ftglRenderLayout, (FTGLlayout *l, const char *s, int r),
+ return, Render, (s, r));
+
+// FT_Error FTLayout::Error() const;
+C_FUN(FT_Error, ftglGetLayoutError, (FTGLlayout *l), return -1, Error, ());
+
+// void FTSimpleLayout::SetFont(FTFont *fontInit)
+void ftglSetLayoutFont(FTGLlayout *l, FTGLfont *font)
+{
+ if(!l || !l->ptr)
+ {
+ fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__);
+ return;
+ }
+ if(l->type != FTGL::LAYOUT_SIMPLE)
+ {
+ fprintf(stderr, "FTGL warning: %s not implemented for %d\n",
+ __FUNCTION__, l->type);
+ }
+ l->font = font;
+ return dynamic_cast<FTSimpleLayout*>(l->ptr)->SetFont(font->ptr);
+}
+
+// FTFont *FTSimpleLayout::GetFont()
+FTGLfont *ftglGetLayoutFont(FTGLlayout *l)
+{
+ if(!l || !l->ptr)
+ {
+ fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__);
+ return NULL;
+ }
+ if(l->type != FTGL::LAYOUT_SIMPLE)
+ {
+ fprintf(stderr, "FTGL warning: %s not implemented for %d\n",
+ __FUNCTION__, l->type);
+ }
+ return l->font;
+}
+
+#undef C_FUN
+
+#define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \
+ cret cname cargs \
+ { \
+ if(!l || !l->ptr) \
+ { \
+ fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \
+ cxxerr; \
+ } \
+ if(l->type != FTGL::LAYOUT_SIMPLE) \
+ { \
+ fprintf(stderr, "FTGL warning: %s not implemented for %d\n", \
+ __FUNCTION__, l->type); \
+ cxxerr; \
+ } \
+ return dynamic_cast<FTSimpleLayout*>(l->ptr)->cxxname cxxarg; \
+ }
+
+// void FTSimpleLayout::SetLineLength(const float LineLength);
+C_FUN(void, ftglSetLayoutLineLength, (FTGLlayout *l, const float length),
+ return, SetLineLength, (length));
+
+// float FTSimpleLayout::GetLineLength() const
+C_FUN(float, ftglGetLayoutLineLength, (FTGLlayout *l),
+ return 0.0f, GetLineLength, ());
+
+// void FTSimpleLayout::SetAlignment(const TextAlignment Alignment)
+C_FUN(void, ftglSetLayoutAlignment, (FTGLlayout *l, const int a),
+ return, SetAlignment, ((FTGL::TextAlignment)a));
+
+// TextAlignment FTSimpleLayout::GetAlignment() const
+C_FUN(int, ftglGetLayoutAlignement, (FTGLlayout *l),
+ return FTGL::ALIGN_LEFT, GetAlignment, ());
+
+// void FTSimpleLayout::SetLineSpacing(const float LineSpacing)
+C_FUN(void, ftglSetLayoutLineSpacing, (FTGLlayout *l, const float f),
+ return, SetLineSpacing, (f));
+
+FTGL_END_C_DECLS
+
diff --git a/src/ftgl/FTLayout/FTLayoutImpl.h b/src/ftgl/FTLayout/FTLayoutImpl.h
new file mode 100644
index 0000000..85df50d
--- /dev/null
+++ b/src/ftgl/FTLayout/FTLayoutImpl.h
@@ -0,0 +1,56 @@
+/*
+ * FTGL - OpenGL font library
+ *
+ * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
+ * Copyright (c) 2008 Sam Hocevar <sam@zoy.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __FTLayoutImpl__
+#define __FTLayoutImpl__
+
+#include "FTSize.h"
+#include "FTGlyphContainer.h"
+
+
+class FTLayoutImpl
+{
+ friend class FTLayout;
+
+ protected:
+ FTLayoutImpl();
+
+ virtual ~FTLayoutImpl();
+
+ protected:
+ /**
+ * Current pen or cursor position;
+ */
+ FTPoint pen;
+
+ /**
+ * Current error code. Zero means no error.
+ */
+ FT_Error err;
+};
+
+#endif // __FTLayoutImpl__
+
diff --git a/src/ftgl/FTLayout/FTSimpleLayout.cpp b/src/ftgl/FTLayout/FTSimpleLayout.cpp
new file mode 100644
index 0000000..b5a7beb
--- /dev/null
+++ b/src/ftgl/FTLayout/FTSimpleLayout.cpp
@@ -0,0 +1,460 @@
+/*
+ * FTGL - OpenGL font library
+ *
+ * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
+ * Copyright (c) 2008 Sam Hocevar <sam@zoy.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <ctype.h>
+#include <wctype.h>
+
+#include "FTInternals.h"
+#include "FTUnicode.h"
+
+#include "FTGlyphContainer.h"
+#include "FTSimpleLayoutImpl.h"
+
+
+//
+// FTSimpleLayout
+//
+
+
+FTSimpleLayout::FTSimpleLayout() :
+ FTLayout(new FTSimpleLayoutImpl())
+{}
+
+
+FTSimpleLayout::~FTSimpleLayout()
+{}
+
+
+FTBBox FTSimpleLayout::BBox(const char *string, const int len, FTPoint pos)
+{
+ return dynamic_cast<FTSimpleLayoutImpl*>(impl)->BBox(string, len, pos);
+}
+
+
+FTBBox FTSimpleLayout::BBox(const wchar_t *string, const int len, FTPoint pos)
+{
+ return dynamic_cast<FTSimpleLayoutImpl*>(impl)->BBox(string, len, pos);
+}
+
+
+void FTSimpleLayout::Render(const char *string, const int len, FTPoint pos,
+ int renderMode)
+{
+ return dynamic_cast<FTSimpleLayoutImpl*>(impl)->Render(string, len, pos,
+ renderMode);
+}
+
+
+void FTSimpleLayout::Render(const wchar_t* string, const int len, FTPoint pos,
+ int renderMode)
+{
+ return dynamic_cast<FTSimpleLayoutImpl*>(impl)->Render(string, len, pos,
+ renderMode);
+}
+
+
+void FTSimpleLayout::SetFont(FTFont *fontInit)
+{
+ dynamic_cast<FTSimpleLayoutImpl*>(impl)->currentFont = fontInit;
+}
+
+
+FTFont *FTSimpleLayout::GetFont()
+{
+ return dynamic_cast<FTSimpleLayoutImpl*>(impl)->currentFont;
+}
+
+
+void FTSimpleLayout::SetLineLength(const float LineLength)
+{
+ dynamic_cast<FTSimpleLayoutImpl*>(impl)->lineLength = LineLength;
+}
+
+
+float FTSimpleLayout::GetLineLength() const
+{
+ return dynamic_cast<FTSimpleLayoutImpl*>(impl)->lineLength;
+}
+
+
+void FTSimpleLayout::SetAlignment(const FTGL::TextAlignment Alignment)
+{
+ dynamic_cast<FTSimpleLayoutImpl*>(impl)->alignment = Alignment;
+}
+
+
+FTGL::TextAlignment FTSimpleLayout::GetAlignment() const
+{
+ return dynamic_cast<FTSimpleLayoutImpl*>(impl)->alignment;
+}
+
+
+void FTSimpleLayout::SetLineSpacing(const float LineSpacing)
+{
+ dynamic_cast<FTSimpleLayoutImpl*>(impl)->lineSpacing = LineSpacing;
+}
+
+
+float FTSimpleLayout::GetLineSpacing() const
+{
+ return dynamic_cast<FTSimpleLayoutImpl*>(impl)->lineSpacing;
+}
+
+
+//
+// FTSimpleLayoutImpl
+//
+
+
+FTSimpleLayoutImpl::FTSimpleLayoutImpl()
+{
+ currentFont = NULL;
+ lineLength = 100.0f;
+ alignment = FTGL::ALIGN_LEFT;
+ lineSpacing = 1.0f;
+}
+
+
+template <typename T>
+inline FTBBox FTSimpleLayoutImpl::BBoxI(const T* string, const int len,
+ FTPoint position)
+{
+ FTBBox tmp;
+
+ WrapText(string, len, position, 0, &tmp);
+
+ return tmp;
+}
+
+
+FTBBox FTSimpleLayoutImpl::BBox(const char *string, const int len,
+ FTPoint position)
+{
+ return BBoxI(string, len, position);
+}
+
+
+FTBBox FTSimpleLayoutImpl::BBox(const wchar_t *string, const int len,
+ FTPoint position)
+{
+ return BBoxI(string, len, position);
+}
+
+
+template <typename T>
+inline void FTSimpleLayoutImpl::RenderI(const T *string, const int len,
+ FTPoint position, int renderMode)
+{
+ pen = FTPoint(0.0f, 0.0f);
+ WrapText(string, len, position, renderMode, NULL);
+}
+
+
+void FTSimpleLayoutImpl::Render(const char *string, const int len,
+ FTPoint position, int renderMode)
+{
+ RenderI(string, len, position, renderMode);
+}
+
+
+void FTSimpleLayoutImpl::Render(const wchar_t* string, const int len,
+ FTPoint position, int renderMode)
+{
+ RenderI(string, len, position, renderMode);
+}
+
+
+template <typename T>
+inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len,
+ FTPoint position, int renderMode,
+ FTBBox *bounds)
+{
+ FTUnicodeStringItr<T> breakItr(buf); // points to the last break character
+ FTUnicodeStringItr<T> lineStart(buf); // points to the line start
+ float nextStart = 0.0; // total width of the current line
+ float breakWidth = 0.0; // width of the line up to the last word break
+ float currentWidth = 0.0; // width of all characters on the current line
+ float prevWidth; // width of all characters but the current glyph
+ float wordLength = 0.0; // length of the block since the last break char
+ int charCount = 0; // number of characters so far on the line
+ int breakCharCount = 0; // number of characters before the breakItr
+ float glyphWidth, advance;
+ FTBBox glyphBounds;
+
+ // Reset the pen position
+ pen.Y(0);
+
+ // If we have bounds mark them invalid
+ if(bounds)
+ {
+ bounds->Invalidate();
+ }
+
+ // Scan the input for all characters that need output
+ FTUnicodeStringItr<T> prevItr(buf);
+ for (FTUnicodeStringItr<T> itr(buf); *itr; prevItr = itr++, charCount++)
+ {
+ // Find the width of the current glyph
+ glyphBounds = currentFont->BBox(itr.getBufferFromHere(), 1);
+ glyphWidth = glyphBounds.Upper().Xf() - glyphBounds.Lower().Xf();
+
+ advance = currentFont->Advance(itr.getBufferFromHere(), 1);
+ prevWidth = currentWidth;
+ // Compute the width of all glyphs up to the end of buf[i]
+ currentWidth = nextStart + glyphWidth;
+ // Compute the position of the next glyph
+ nextStart += advance;
+
+ // See if the current character is a space, a break or a regular character
+ if((currentWidth > lineLength) || (*itr == '\n'))
+ {
+ // A non whitespace character has exceeded the line length. Or a
+ // newline character has forced a line break. Output the last
+ // line and start a new line after the break character.
+ // If we have not yet found a break, break on the last character
+ if(breakItr == lineStart || (*itr == '\n'))
+ {
+ // Break on the previous character
+ breakItr = prevItr;
+ breakCharCount = charCount - 1;
+ breakWidth = prevWidth;
+ // None of the previous words will be carried to the next line
+ wordLength = 0;
+ // If the current character is a newline discard its advance
+ if(*itr == '\n') advance = 0;
+ }
+
+ float remainingWidth = lineLength - breakWidth;
+
+ // Render the current substring
+ FTUnicodeStringItr<T> breakChar = breakItr;
+ // move past the break character and don't count it on the next line either
+ ++breakChar; --charCount;
+ // If the break character is a newline do not render it
+ if(*breakChar == '\n')
+ {
+ ++breakChar; --charCount;
+ }
+
+ OutputWrapped(lineStart.getBufferFromHere(), breakCharCount,
+ //breakItr.getBufferFromHere() - lineStart.getBufferFromHere(),
+ position, renderMode, remainingWidth, bounds);
+
+ // Store the start of the next line
+ lineStart = breakChar;
+ // TODO: Is Height() the right value here?
+ pen -= FTPoint(0, currentFont->LineHeight() * lineSpacing);
+ // The current width is the width since the last break
+ nextStart = wordLength + advance;
+ wordLength += advance;
+ currentWidth = wordLength + advance;
+ // Reset the safe break for the next line
+ breakItr = lineStart;
+ charCount -= breakCharCount;
+ }
+ else if(iswspace(*itr))
+ {
+ // This is the last word break position
+ wordLength = 0;
+ breakItr = itr;
+ breakCharCount = charCount;
+
+ // Check to see if this is the first whitespace character in a run
+ if(buf == itr.getBufferFromHere() || !iswspace(*prevItr))
+ {
+ // Record the width of the start of the block
+ breakWidth = currentWidth;
+ }
+ }
+ else
+ {
+ wordLength += advance;
+ }
+ }
+
+ float remainingWidth = lineLength - currentWidth;
+ // Render any remaining text on the last line
+ // Disable justification for the last row
+ if(alignment == FTGL::ALIGN_JUSTIFY)
+ {
+ alignment = FTGL::ALIGN_LEFT;
+ OutputWrapped(lineStart.getBufferFromHere(), -1, position, renderMode,
+ remainingWidth, bounds);
+ alignment = FTGL::ALIGN_JUSTIFY;
+ }
+ else
+ {
+ OutputWrapped(lineStart.getBufferFromHere(), -1, position, renderMode,
+ remainingWidth, bounds);
+ }
+}
+
+
+void FTSimpleLayoutImpl::WrapText(const char *buf, const int len,
+ FTPoint position, int renderMode,
+ FTBBox *bounds)
+{
+ WrapTextI(buf, len, position, renderMode, bounds);
+}
+
+
+void FTSimpleLayoutImpl::WrapText(const wchar_t* buf, const int len,
+ FTPoint position, int renderMode,
+ FTBBox *bounds)
+{
+ WrapTextI(buf, len, position, renderMode, bounds);
+}
+
+
+template <typename T>
+inline void FTSimpleLayoutImpl::OutputWrappedI(const T *buf, const int len,
+ FTPoint position, int renderMode,
+ const float remaining,
+ FTBBox *bounds)
+{
+ float distributeWidth = 0.0;
+ // Align the text according as specified by Alignment
+ switch (alignment)
+ {
+ case FTGL::ALIGN_LEFT:
+ pen.X(0);
+ break;
+ case FTGL::ALIGN_CENTER:
+ pen.X(remaining / 2);
+ break;
+ case FTGL::ALIGN_RIGHT:
+ pen.X(remaining);
+ break;
+ case FTGL::ALIGN_JUSTIFY:
+ pen.X(0);
+ distributeWidth = remaining;
+ break;
+ }
+
+ // If we have bounds expand them by the line's bounds, otherwise render
+ // the line.
+ if(bounds)
+ {
+ FTBBox temp = currentFont->BBox(buf, len);
+
+ // Add the extra space to the upper x dimension
+ temp = FTBBox(temp.Lower() + pen,
+ temp.Upper() + pen + FTPoint(distributeWidth, 0));
+
+ // See if this is the first area to be added to the bounds
+ if(bounds->IsValid())
+ {
+ *bounds |= temp;
+ }
+ else
+ {
+ *bounds = temp;
+ }
+ }
+ else
+ {
+ RenderSpace(buf, len, position, renderMode, distributeWidth);
+ }
+}
+
+
+void FTSimpleLayoutImpl::OutputWrapped(const char *buf, const int len,
+ FTPoint position, int renderMode,
+ const float remaining, FTBBox *bounds)
+{
+ OutputWrappedI(buf, len, position, renderMode, remaining, bounds);
+}
+
+
+void FTSimpleLayoutImpl::OutputWrapped(const wchar_t *buf, const int len,
+ FTPoint position, int renderMode,
+ const float remaining, FTBBox *bounds)
+{
+ OutputWrappedI(buf, len, position, renderMode, remaining, bounds);
+}
+
+
+template <typename T>
+inline void FTSimpleLayoutImpl::RenderSpaceI(const T *string, const int len,
+ FTPoint position, int renderMode,
+ const float extraSpace)
+{
+ float space = 0.0;
+
+ // If there is space to distribute, count the number of spaces
+ if(extraSpace > 0.0)
+ {
+ int numSpaces = 0;
+
+ // Count the number of space blocks in the input
+ FTUnicodeStringItr<T> prevItr(string), itr(string);
+ for(int i = 0; ((len < 0) && *itr) || ((len >= 0) && (i <= len));
+ ++i, prevItr = itr++)
+ {
+ // If this is the end of a space block, increment the counter
+ if((i > 0) && !iswspace(*itr) && iswspace(*prevItr))
+ {
+ numSpaces++;
+ }
+ }
+
+ space = extraSpace/numSpaces;
+ }
+
+ // Output all characters of the string
+ FTUnicodeStringItr<T> prevItr(string), itr(string);
+ for(int i = 0; ((len < 0) && *itr) || ((len >= 0) && (i <= len));
+ ++i, prevItr = itr++)
+ {
+ // If this is the end of a space block, distribute the extra space
+ // inside it
+ if((i > 0) && !iswspace(*itr) && iswspace(*prevItr))
+ {
+ pen += FTPoint(space, 0);
+ }
+
+ pen = currentFont->Render(itr.getBufferFromHere(), 1, pen, FTPoint(), renderMode);
+ }
+}
+
+
+void FTSimpleLayoutImpl::RenderSpace(const char *string, const int len,
+ FTPoint position, int renderMode,
+ const float extraSpace)
+{
+ RenderSpaceI(string, len, position, renderMode, extraSpace);
+}
+
+
+void FTSimpleLayoutImpl::RenderSpace(const wchar_t *string, const int len,
+ FTPoint position, int renderMode,
+ const float extraSpace)
+{
+ RenderSpaceI(string, len, position, renderMode, extraSpace);
+}
+
diff --git a/src/ftgl/FTLayout/FTSimpleLayoutImpl.h b/src/ftgl/FTLayout/FTSimpleLayoutImpl.h
new file mode 100644
index 0000000..96a074d
--- /dev/null
+++ b/src/ftgl/FTLayout/FTSimpleLayoutImpl.h
@@ -0,0 +1,225 @@
+/*
+ * FTGL - OpenGL font library
+ *
+ * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
+ * Copyright (c) 2008 Sam Hocevar <sam@zoy.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __FTSimpleLayoutImpl__
+#define __FTSimpleLayoutImpl__
+
+#include "FTLayoutImpl.h"
+
+
+class FTFont;
+
+class FTSimpleLayoutImpl : public FTLayoutImpl
+{
+ friend class FTSimpleLayout;
+
+ protected:
+ FTSimpleLayoutImpl();
+
+ virtual ~FTSimpleLayoutImpl() {};
+
+ virtual FTBBox BBox(const char* string, const int len,
+ FTPoint position);
+
+ virtual FTBBox BBox(const wchar_t* string, const int len,
+ FTPoint position);
+
+ virtual void Render(const char *string, const int len,
+ FTPoint position, int renderMode);
+
+ virtual void Render(const wchar_t *string, const int len,
+ FTPoint position, int renderMode);
+
+ /**
+ * Render a string of characters and distribute extra space amongst
+ * the whitespace regions of the string.
+ *
+ * @param string A buffer of wchar_t characters to output.
+ * @param len The length of the string. If < 0 then all characters
+ * will be displayed until a null character is encountered.
+ * @param position TODO
+ * @param renderMode Render mode to display
+ * @param extraSpace The amount of extra space to distribute amongst
+ * the characters.
+ */
+ virtual void RenderSpace(const char *string, const int len,
+ FTPoint position, int renderMode,
+ const float extraSpace);
+
+ /**
+ * Render a string of characters and distribute extra space amongst
+ * the whitespace regions of the string.
+ *
+ * @param string A buffer of wchar_t characters to output.
+ * @param len The length of the string. If < 0 then all characters
+ * will be displayed until a null character is encountered.
+ * @param position TODO
+ * @param renderMode Render mode to display
+ * @param extraSpace The amount of extra space to distribute amongst
+ * the characters.
+ */
+ virtual void RenderSpace(const wchar_t *string, const int len,
+ FTPoint position, int renderMode,
+ const float extraSpace);
+
+ private:
+ /**
+ * Either render a string of characters and wrap lines
+ * longer than a threshold or compute the bounds
+ * of a string of characters when wrapped. The functionality
+ * of this method is exposed by the BBoxWrapped and
+ * RenderWrapped methods.
+ *
+ * @param buf A char string to output.
+ * @param len The length of the string. If < 0 then all characters
+ * will be displayed until a null character is encountered.
+ * @param position TODO
+ * @param renderMode Render mode to display
+ * @param bounds A pointer to a bounds object. If non null
+ * the bounds of the text when laid out
+ * will be stored in bounds. If null the
+ * text will be rendered.
+ */
+ virtual void WrapText(const char *buf, const int len,
+ FTPoint position, int renderMode,
+ FTBBox *bounds);
+
+ /**
+ * Either render a string of characters and wrap lines
+ * longer than a threshold or compute the bounds
+ * of a string of characters when wrapped. The functionality
+ * of this method is exposed by the BBoxWrapped and
+ * RenderWrapped methods.
+ *
+ * @param buf A wchar_t style string to output.
+ * @param len The length of the string. If < 0 then all characters
+ * will be displayed until a null character is encountered.
+ * @param position TODO
+ * @param renderMode Render mode to display
+ * @param bounds A pointer to a bounds object. If non null
+ * the bounds of the text when laid out
+ * will be stored in bounds. If null the
+ * text will be rendered.
+ */
+ virtual void WrapText(const wchar_t *buf, const int len,
+ FTPoint position, int renderMode,
+ FTBBox *bounds);
+
+ /**
+ * A helper method used by WrapText to either output the text or
+ * compute it's bounds.
+ *
+ * @param buf A pointer to an array of character data.
+ * @param len The length of the string. If < 0 then all characters
+ * will be displayed until a null character is encountered.
+ * @param position TODO
+ * @param renderMode Render mode to display
+ * @param RemainingWidth The amount of extra space left on the line.
+ * @param bounds A pointer to a bounds object. If non null the
+ * bounds will be initialized or expanded by the
+ * bounds of the line. If null the text will be
+ * rendered. If the bounds are invalid (lower > upper)
+ * they will be initialized. Otherwise they
+ * will be expanded.
+ */
+ void OutputWrapped(const char *buf, const int len,
+ FTPoint position, int renderMode,
+ const float RemainingWidth, FTBBox *bounds);
+
+ /**
+ * A helper method used by WrapText to either output the text or
+ * compute it's bounds.
+ *
+ * @param buf A pointer to an array of character data.
+ * @param len The length of the string. If < 0 then all characters
+ * will be displayed until a null character is encountered.
+ * @param position TODO
+ * @param renderMode Render mode to display
+ * @param RemainingWidth The amount of extra space left on the line.
+ * @param bounds A pointer to a bounds object. If non null the
+ * bounds will be initialized or expanded by the
+ * bounds of the line. If null the text will be
+ * rendered. If the bounds are invalid (lower > upper)
+ * they will be initialized. Otherwise they
+ * will be expanded.
+ */
+ void OutputWrapped(const wchar_t *buf, const int len,
+ FTPoint position, int renderMode,
+ const float RemainingWidth, FTBBox *bounds);
+
+ /**
+ * The font to use for rendering the text. The font is
+ * referenced by this but will not be disposed of when this
+ * is deleted.
+ */
+ FTFont *currentFont;
+
+ /**
+ * The maximum line length for formatting text.
+ */
+ float lineLength;
+
+ /**
+ * The text alignment mode used to distribute
+ * space within a line or rendered text.
+ */
+ FTGL::TextAlignment alignment;
+
+ /**
+ * The height of each line of text expressed as
+ * a percentage of the font's line height.
+ */
+ float lineSpacing;
+
+ /* Internal generic BBox() implementation */
+ template <typename T>
+ inline FTBBox BBoxI(const T* string, const int len, FTPoint position);
+
+ /* Internal generic Render() implementation */
+ template <typename T>
+ inline void RenderI(const T* string, const int len,
+ FTPoint position, int renderMode);
+
+ /* Internal generic RenderSpace() implementation */
+ template <typename T>
+ inline void RenderSpaceI(const T* string, const int len,
+ FTPoint position, int renderMode,
+ const float extraSpace);
+
+ /* Internal generic WrapText() implementation */
+ template <typename T>
+ void WrapTextI(const T* buf, const int len, FTPoint position,
+ int renderMode, FTBBox *bounds);
+
+ /* Internal generic OutputWrapped() implementation */
+ template <typename T>
+ void OutputWrappedI(const T* buf, const int len, FTPoint position,
+ int renderMode, const float RemainingWidth,
+ FTBBox *bounds);
+};
+
+#endif // __FTSimpleLayoutImpl__
+