00001 /* 00002 Copyright (c) 2010, The Barbarian Group 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00006 the following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00009 the following disclaimer. 00010 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00011 the following disclaimer in the documentation and/or other materials provided with the distribution. 00012 00013 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00014 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00015 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00016 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00017 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00018 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00019 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00020 POSSIBILITY OF SUCH DAMAGE. 00021 */ 00022 00023 #pragma once 00024 00025 #include "cinder/Cinder.h" 00026 #include "cinder/Shape2d.h" 00027 #include "cinder/Exception.h" 00028 #include "cinder/DataSource.h" 00029 00030 #include <string> 00031 #include <vector> 00032 00033 #if defined( CINDER_COCOA ) 00034 typedef struct CGFont *CGFontRef; 00035 #if defined( CINDER_COCOA ) 00036 typedef const struct __CTFont * CTFontRef; 00037 #endif 00038 #elif defined( CINDER_MSW ) 00039 #include <windows.h> 00040 #undef min 00041 #undef max 00042 00043 namespace Gdiplus { 00044 class Font; 00045 } 00046 #endif 00047 00048 namespace cinder { 00049 00051 class Font { 00052 public: 00053 typedef uint16_t Glyph; 00054 00056 Font() {} 00059 Font( const std::string &aName, float size ); 00062 Font( DataSourceRef dataSource, float size ); 00063 00064 const std::string& getName() const; 00065 std::string getFullName() const; 00066 float getSize() const; 00067 00068 float getLeading() const; 00069 float getAscent() const; 00070 float getDescent() const; 00071 size_t getNumGlyphs() const; 00072 00073 Glyph getGlyphIndex( size_t idx ) const; 00074 Glyph getGlyphChar( char utf8Char ) const; 00075 std::vector<Glyph> getGlyphs( const std::string &utf8String ) const; 00077 Shape2d getGlyphShape( Glyph glyphIndex ) const; 00079 Rectf getGlyphBoundingBox( Glyph glyph ) const; 00080 00081 static const std::vector<std::string>& getNames( bool forceRefresh = false ); 00082 static Font getDefault(); 00083 00084 #if defined( CINDER_COCOA ) 00085 CGFontRef getCgFontRef() const; 00086 CTFontRef getCtFontRef() const; 00087 #elif defined( CINDER_MSW ) 00088 ::LOGFONT getLogfont() const { return mObj->mLogFont; } 00089 ::HFONT getHfont() const { return mObj->mHfont; } 00090 const Gdiplus::Font* getGdiplusFont() const { return mObj->mGdiplusFont.get(); } 00091 static HDC getGlobalDc(); 00092 #endif 00093 00094 private: 00095 class Obj { 00096 public: 00097 Obj( const std::string &aName, float aSize ); 00098 Obj( DataSourceRef dataSource, float size ); 00099 ~Obj(); 00100 00101 void finishSetup(); 00102 00103 00104 std::string mName; 00105 float mSize; 00106 #if defined( CINDER_COCOA ) 00107 CGFontRef mCGFont; 00108 const struct __CTFont* mCTFont; 00109 #elif defined( CINDER_MSW ) 00110 ::TEXTMETRIC mTextMetric; 00111 ::LOGFONTW mLogFont; 00112 ::HFONT mHfont; 00113 std::shared_ptr<Gdiplus::Font> mGdiplusFont; 00114 std::vector<std::pair<uint16_t,uint16_t> > mUnicodeRanges; 00115 size_t mNumGlyphs; 00116 #endif 00117 }; 00118 00119 std::shared_ptr<Obj> mObj; 00120 00121 public: 00123 00124 typedef std::shared_ptr<Obj> Font::*unspecified_bool_type; 00125 operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &Font::mObj; } 00126 void reset() { mObj.reset(); } 00128 }; 00129 00130 class FontInvalidNameExc : public cinder::Exception { 00131 public: 00132 FontInvalidNameExc() throw() {} 00133 FontInvalidNameExc( const std::string &fontName ) throw(); 00134 virtual const char* what() const throw() { return mMessage; } 00135 private: 00136 char mMessage[2048]; 00137 }; 00138 00139 class FontGlyphFailureExc : public cinder::Exception { 00140 }; 00141 00142 } // namespace cinder