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 00027 #include "cinder/Surface.h" 00028 #include "cinder/Font.h" 00029 #include "cinder/Vector.h" 00030 00031 #include <vector> 00032 #include <deque> 00033 #include <string> 00034 00035 // Core Text forward declarations 00036 #if defined( CINDER_COCOA ) 00037 struct __CTFrame; 00038 struct __CTLine; 00039 #endif 00040 00041 namespace cinder { 00042 00043 class TextLayout { 00044 public: 00050 TextLayout(); 00051 00053 void clear( const Color &color ); 00055 void clear( const ColorA &color ); 00056 00058 void addLine( const std::string &line ); 00060 void addCenteredLine( const std::string &line ); 00062 void addRightLine( const std::string &line ); 00064 void append( const std::string &str ); 00065 00066 void setFont( const Font &font ); 00068 void setColor( const Color &color ); 00070 void setColor( const ColorA &color ); 00072 void setLeadingOffset( float leadingOffset ); 00073 00075 void setBorder( int horizontal, int vertical ); 00076 00078 Surface render( bool useAlpha = false, bool premultiplied = false ); 00079 00080 private: 00081 ColorA mBackgroundColor; 00082 Font mCurrentFont; 00083 ColorA mCurrentColor; 00084 float mCurrentLeadingOffset; 00085 int mHorizontalBorder, mVerticalBorder; 00086 00087 std::deque<std::shared_ptr<class Line> > mLines; 00088 }; 00089 00090 class TextBox { 00091 public: 00092 typedef enum Alignment { LEFT, CENTER, RIGHT } Alignment; 00093 enum { GROW = 0 }; 00094 00095 TextBox() : mAlign( LEFT ), mSize( GROW, GROW ), mFont( Font::getDefault() ), mInvalid( true ), mColor( 1, 1, 1, 1 ), mBackgroundColor( 0, 0, 0, 0 ), mPremultiplied( false ), mLigate( true ) {} 00096 00097 TextBox& size( Vec2i sz ) { setSize( sz ); return *this; } 00098 TextBox& size( int width, int height ) { setSize( Vec2i( width, height ) ); return *this; } 00099 Vec2i getSize() const { return mSize; } 00100 void setSize( Vec2i sz ) { mSize = sz; mInvalid = true; } 00101 00102 TextBox& text( const std::string &t ) { setText( t ); return *this; } 00103 const std::string& getText() const { return mText; } 00104 void setText( const std::string &t ) { mText = t; mInvalid = true; } 00105 void appendText( const std::string &t ) { mText += t; mInvalid = true; } 00106 00107 TextBox& font( const Font &f ) { setFont( f ); return *this; } 00108 const Font& getFont() const { return mFont; } 00109 void setFont( const Font &f ) { mFont = f; mInvalid = true; } 00110 00111 TextBox& alignment( Alignment align ) { setAlignment( align ); return *this; } 00112 Alignment getAlignment() const { return mAlign; } 00113 void setAlignment( Alignment align ) { mAlign = align; mInvalid = true; } 00114 00115 TextBox& color( ColorA color ) { setColor( color ); return *this; } 00116 ColorA getColor() const { return mColor; } 00117 void setColor( ColorA color ) { mColor = color; mInvalid = true; } 00118 00119 TextBox& backgroundColor( ColorA bgColor ) { setBackgroundColor( bgColor ); return *this; } 00120 ColorA getBackgroundColor() const { return mBackgroundColor; } 00121 void setBackgroundColor( ColorA bgColor ) { mBackgroundColor = bgColor; } 00122 00123 TextBox& premultiplied( bool premult = true ) { setPremultiplied( premult ); return *this; } 00124 bool getPremultiplied() const { return mPremultiplied; } 00125 void setPremultiplied( bool premult ) { mPremultiplied = premult; } 00126 00127 TextBox& ligate( bool ligateText = true ) { setLigate( ligateText ); return *this; } 00128 bool getLigate() const { return mLigate; } 00129 void setLigate( bool ligateText ) { mLigate = ligateText; } 00130 00131 Vec2f measure() const; 00134 std::vector<std::pair<uint16_t,Vec2f> > measureGlyphs() const; 00135 00136 Surface render( Vec2f offset = Vec2f::zero() ); 00137 00138 protected: 00139 Alignment mAlign; 00140 Vec2i mSize; 00141 std::string mText; 00142 Font mFont; 00143 ColorA mColor, mBackgroundColor; 00144 bool mPremultiplied; 00145 bool mLigate; 00146 mutable bool mInvalid; 00147 00148 mutable Vec2f mCalculatedSize; 00149 #if defined( CINDER_COCOA ) 00150 void createLines() const; 00151 00152 mutable std::vector<std::pair<std::shared_ptr<const __CTLine>,Vec2f> > mLines; 00153 #elif defined( CINDER_MSW ) 00154 std::vector<std::string> calculateLineBreaks() const; 00155 void calculate() const; 00156 00157 mutable std::wstring mWideText; 00158 #endif 00159 }; 00160 00165 #if defined( CINDER_COCOA_TOUCH ) 00166 Surface renderStringPow2( const std::string &str, const Font &font, const ColorA &color, Vec2i *actualSize, float *baselineOffset = 0 ); 00167 #else 00168 Surface renderString( const std::string &str, const Font &font, const ColorA &color, float *baselineOffset = 0 ); 00169 #endif 00170 00171 } // namespace cinder