summaryrefslogtreecommitdiff
path: root/src/ftgl/FTFont/FTFont.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ftgl/FTFont/FTFont.cpp')
-rw-r--r--src/ftgl/FTFont/FTFont.cpp552
1 files changed, 552 insertions, 0 deletions
diff --git a/src/ftgl/FTFont/FTFont.cpp b/src/ftgl/FTFont/FTFont.cpp
new file mode 100644
index 0000000..a7206fb
--- /dev/null
+++ b/src/ftgl/FTFont/FTFont.cpp
@@ -0,0 +1,552 @@
+/*
+ * 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 "FTInternals.h"
+#include "FTUnicode.h"
+
+#include "FTFontImpl.h"
+
+#include "FTBitmapFontImpl.h"
+#include "FTExtrudeFontImpl.h"
+#include "FTOutlineFontImpl.h"
+#include "FTPixmapFontImpl.h"
+#include "FTPolygonFontImpl.h"
+#include "FTTextureFontImpl.h"
+
+#include "FTGlyphContainer.h"
+#include "FTFace.h"
+
+
+//
+// FTFont
+//
+
+
+FTFont::FTFont(char const *fontFilePath)
+{
+ impl = new FTFontImpl(this, fontFilePath);
+}
+
+
+FTFont::FTFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
+{
+ impl = new FTFontImpl(this, pBufferBytes, bufferSizeInBytes);
+}
+
+
+FTFont::FTFont(FTFontImpl *pImpl)
+{
+ impl = pImpl;
+}
+
+
+FTFont::~FTFont()
+{
+ delete impl;
+}
+
+
+bool FTFont::Attach(const char* fontFilePath)
+{
+ return impl->Attach(fontFilePath);
+}
+
+
+bool FTFont::Attach(const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
+{
+ return impl->Attach(pBufferBytes, bufferSizeInBytes);
+}
+
+
+bool FTFont::FaceSize(const unsigned int size, const unsigned int res)
+{
+ return impl->FaceSize(size, res);
+}
+
+
+unsigned int FTFont::FaceSize() const
+{
+ return impl->FaceSize();
+}
+
+
+void FTFont::Depth(float depth)
+{
+ return impl->Depth(depth);
+}
+
+
+void FTFont::Outset(float outset)
+{
+ return impl->Outset(outset);
+}
+
+
+void FTFont::Outset(float front, float back)
+{
+ return impl->Outset(front, back);
+}
+
+
+void FTFont::GlyphLoadFlags(FT_Int flags)
+{
+ return impl->GlyphLoadFlags(flags);
+}
+
+
+bool FTFont::CharMap(FT_Encoding encoding)
+{
+ return impl->CharMap(encoding);
+}
+
+
+unsigned int FTFont::CharMapCount() const
+{
+ return impl->CharMapCount();
+}
+
+
+FT_Encoding* FTFont::CharMapList()
+{
+ return impl->CharMapList();
+}
+
+
+void FTFont::UseDisplayList(bool useList)
+{
+ return impl->UseDisplayList(useList);
+}
+
+
+float FTFont::Ascender() const
+{
+ return impl->Ascender();
+}
+
+
+float FTFont::Descender() const
+{
+ return impl->Descender();
+}
+
+
+float FTFont::LineHeight() const
+{
+ return impl->LineHeight();
+}
+
+
+FTPoint FTFont::Render(const char * string, const int len,
+ FTPoint position, FTPoint spacing, int renderMode)
+{
+ return impl->Render(string, len, position, spacing, renderMode);
+}
+
+
+FTPoint FTFont::Render(const wchar_t * string, const int len,
+ FTPoint position, FTPoint spacing, int renderMode)
+{
+ return impl->Render(string, len, position, spacing, renderMode);
+}
+
+
+float FTFont::Advance(const char * string, const int len, FTPoint spacing)
+{
+ return impl->Advance(string, len, spacing);
+}
+
+
+float FTFont::Advance(const wchar_t * string, const int len, FTPoint spacing)
+{
+ return impl->Advance(string, len, spacing);
+}
+
+
+FTBBox FTFont::BBox(const char *string, const int len,
+ FTPoint position, FTPoint spacing)
+{
+ return impl->BBox(string, len, position, spacing);
+}
+
+
+FTBBox FTFont::BBox(const wchar_t *string, const int len,
+ FTPoint position, FTPoint spacing)
+{
+ return impl->BBox(string, len, position, spacing);
+}
+
+
+FT_Error FTFont::Error() const
+{
+ return impl->err;
+}
+
+
+//
+// FTFontImpl
+//
+
+
+FTFontImpl::FTFontImpl(FTFont *ftFont, char const *fontFilePath) :
+ face(fontFilePath),
+ useDisplayLists(true),
+ load_flags(FT_LOAD_DEFAULT),
+ intf(ftFont),
+ glyphList(0)
+{
+ err = face.Error();
+ if(err == 0)
+ {
+ glyphList = new FTGlyphContainer(&face);
+ }
+}
+
+
+FTFontImpl::FTFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes,
+ size_t bufferSizeInBytes) :
+ face(pBufferBytes, bufferSizeInBytes),
+ useDisplayLists(true),
+ load_flags(FT_LOAD_DEFAULT),
+ intf(ftFont),
+ glyphList(0)
+{
+ err = face.Error();
+ if(err == 0)
+ {
+ glyphList = new FTGlyphContainer(&face);
+ }
+}
+
+
+FTFontImpl::~FTFontImpl()
+{
+ if(glyphList)
+ {
+ delete glyphList;
+ }
+}
+
+
+bool FTFontImpl::Attach(const char* fontFilePath)
+{
+ if(!face.Attach(fontFilePath))
+ {
+ err = face.Error();
+ return false;
+ }
+
+ err = 0;
+ return true;
+}
+
+
+bool FTFontImpl::Attach(const unsigned char *pBufferBytes,
+ size_t bufferSizeInBytes)
+{
+ if(!face.Attach(pBufferBytes, bufferSizeInBytes))
+ {
+ err = face.Error();
+ return false;
+ }
+
+ err = 0;
+ return true;
+}
+
+
+bool FTFontImpl::FaceSize(const unsigned int size, const unsigned int res)
+{
+ if(glyphList != NULL)
+ {
+ delete glyphList;
+ glyphList = NULL;
+ }
+
+ charSize = face.Size(size, res);
+ err = face.Error();
+
+ if(err != 0)
+ {
+ return false;
+ }
+
+ glyphList = new FTGlyphContainer(&face);
+ return true;
+}
+
+
+unsigned int FTFontImpl::FaceSize() const
+{
+ return charSize.CharSize();
+}
+
+
+void FTFontImpl::Depth(float depth)
+{
+ ;
+}
+
+
+void FTFontImpl::Outset(float outset)
+{
+ ;
+}
+
+
+void FTFontImpl::Outset(float front, float back)
+{
+ ;
+}
+
+
+void FTFontImpl::GlyphLoadFlags(FT_Int flags)
+{
+ load_flags = flags;
+}
+
+
+bool FTFontImpl::CharMap(FT_Encoding encoding)
+{
+ bool result = glyphList->CharMap(encoding);
+ err = glyphList->Error();
+ return result;
+}
+
+
+unsigned int FTFontImpl::CharMapCount() const
+{
+ return face.CharMapCount();
+}
+
+
+FT_Encoding* FTFontImpl::CharMapList()
+{
+ return face.CharMapList();
+}
+
+
+void FTFontImpl::UseDisplayList(bool useList)
+{
+ useDisplayLists = useList;
+}
+
+
+float FTFontImpl::Ascender() const
+{
+ return charSize.Ascender();
+}
+
+
+float FTFontImpl::Descender() const
+{
+ return charSize.Descender();
+}
+
+
+float FTFontImpl::LineHeight() const
+{
+ return charSize.Height();
+}
+
+
+template <typename T>
+inline FTBBox FTFontImpl::BBoxI(const T* string, const int len,
+ FTPoint position, FTPoint spacing)
+{
+ FTBBox totalBBox;
+
+ /* Only compute the bounds if string is non-empty. */
+ if(string && ('\0' != string[0]))
+ {
+ // for multibyte - we can't rely on sizeof(T) == character
+ FTUnicodeStringItr<T> ustr(string);
+ unsigned int thisChar = *ustr++;
+ unsigned int nextChar = *ustr;
+
+ if(CheckGlyph(thisChar))
+ {
+ totalBBox = glyphList->BBox(thisChar);
+ totalBBox += position;
+
+ position += FTPoint(glyphList->Advance(thisChar, nextChar), 0.0);
+ }
+
+ /* Expand totalBox by each glyph in string */
+ for(int i = 1; (len < 0 && *ustr) || (len >= 0 && i < len); i++)
+ {
+ thisChar = *ustr++;
+ nextChar = *ustr;
+
+ if(CheckGlyph(thisChar))
+ {
+ position += spacing;
+
+ FTBBox tempBBox = glyphList->BBox(thisChar);
+ tempBBox += position;
+ totalBBox |= tempBBox;
+
+ position += FTPoint(glyphList->Advance(thisChar, nextChar),
+ 0.0);
+ }
+ }
+ }
+
+ return totalBBox;
+}
+
+
+FTBBox FTFontImpl::BBox(const char *string, const int len,
+ FTPoint position, FTPoint spacing)
+{
+ /* The chars need to be unsigned because they are cast to int later */
+ return BBoxI((const unsigned char *)string, len, position, spacing);
+}
+
+
+FTBBox FTFontImpl::BBox(const wchar_t *string, const int len,
+ FTPoint position, FTPoint spacing)
+{
+ return BBoxI(string, len, position, spacing);
+}
+
+
+template <typename T>
+inline float FTFontImpl::AdvanceI(const T* string, const int len,
+ FTPoint spacing)
+{
+ float advance = 0.0f;
+ FTUnicodeStringItr<T> ustr(string);
+
+ for(int i = 0; (len < 0 && *ustr) || (len >= 0 && i < len); i++)
+ {
+ unsigned int thisChar = *ustr++;
+ unsigned int nextChar = *ustr;
+
+ if(CheckGlyph(thisChar))
+ {
+ advance += glyphList->Advance(thisChar, nextChar);
+ }
+
+ if(nextChar)
+ {
+ advance += spacing.Xf();
+ }
+ }
+
+ return advance;
+}
+
+
+float FTFontImpl::Advance(const char* string, const int len, FTPoint spacing)
+{
+ /* The chars need to be unsigned because they are cast to int later */
+ return AdvanceI((const unsigned char *)string, len, spacing);
+}
+
+
+float FTFontImpl::Advance(const wchar_t* string, const int len, FTPoint spacing)
+{
+ return AdvanceI(string, len, spacing);
+}
+
+
+template <typename T>
+inline FTPoint FTFontImpl::RenderI(const T* string, const int len,
+ FTPoint position, FTPoint spacing,
+ int renderMode)
+{
+ // for multibyte - we can't rely on sizeof(T) == character
+ FTUnicodeStringItr<T> ustr(string);
+
+ for(int i = 0; (len < 0 && *ustr) || (len >= 0 && i < len); i++)
+ {
+ unsigned int thisChar = *ustr++;
+ unsigned int nextChar = *ustr;
+
+ if(CheckGlyph(thisChar))
+ {
+ position += glyphList->Render(thisChar, nextChar,
+ position, renderMode);
+ }
+
+ if(nextChar)
+ {
+ position += spacing;
+ }
+ }
+
+ return position;
+}
+
+
+FTPoint FTFontImpl::Render(const char * string, const int len,
+ FTPoint position, FTPoint spacing, int renderMode)
+{
+ return RenderI((const unsigned char *)string,
+ len, position, spacing, renderMode);
+}
+
+
+FTPoint FTFontImpl::Render(const wchar_t * string, const int len,
+ FTPoint position, FTPoint spacing, int renderMode)
+{
+ return RenderI(string, len, position, spacing, renderMode);
+}
+
+
+bool FTFontImpl::CheckGlyph(const unsigned int characterCode)
+{
+ if(glyphList->Glyph(characterCode))
+ {
+ return true;
+ }
+
+ unsigned int glyphIndex = glyphList->FontIndex(characterCode);
+ FT_GlyphSlot ftSlot = face.Glyph(glyphIndex, load_flags);
+ if(!ftSlot)
+ {
+ err = face.Error();
+ return false;
+ }
+
+ FTGlyph* tempGlyph = intf->MakeGlyph(ftSlot);
+ if(!tempGlyph)
+ {
+ if(0 == err)
+ {
+ err = 0x13;
+ }
+
+ return false;
+ }
+
+ glyphList->Add(tempGlyph, characterCode);
+
+ return true;
+}
+