nux-1.16.0
StaticText.cpp
00001 #include "Nux.h"
00002 #include "Layout.h"
00003 #include "HLayout.h"
00004 #include "VLayout.h"
00005 #include "Validator.h"
00006 
00007 #include "cairo/cairo.h"
00008 #include "pango/pango.h"
00009 #include "pango/pangocairo.h"
00010 #include "NuxImage/CairoGraphics.h"
00011 
00012 #include "StaticText.h"
00013 
00014 namespace nux
00015 {
00016   StaticText::StaticText (const TCHAR* text, NUX_FILE_LINE_DECL)
00017     : View (NUX_FILE_LINE_PARAM)
00018   {
00019     _size_match_text = true;
00020     _textColor  = color::White;
00021     _texture2D  = 0;
00022     _font_string = g_strdup ("Ubuntu 10");
00023     _clipping = 0;
00024 
00025     SetMinimumSize (DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT);
00026     SetText (text);
00027   }
00028 
00029   StaticText::~StaticText ()
00030   {
00031     if (_cairoGraphics != 0)
00032       delete (_cairoGraphics);
00033 
00034     if (_texture2D != 0)
00035       _texture2D->UnReference ();
00036 
00037     if (_font_string)
00038       g_free (_font_string);
00039   }
00040 
00041   void StaticText::PreLayoutManagement ()
00042   {
00043     int          textWidth  = 0;
00044     int          textHeight = 0;
00045 
00046     GetTextSize (textWidth, textHeight, _clipping);
00047 
00048     _pre_layout_width = GetBaseWidth ();
00049     _pre_layout_height = GetBaseHeight ();
00050 
00051     SetBaseSize (textWidth, textHeight);
00052 
00053     if (_texture2D == 0)
00054     {
00055       UpdateTextRendering ();
00056     }
00057 
00058     View::PreLayoutManagement ();
00059   }
00060 
00061   long StaticText::PostLayoutManagement (long layoutResult)
00062   {
00063     //  long result = View::PostLayoutManagement (layoutResult);
00064 
00065     long result = 0;
00066 
00067     int w = GetBaseWidth();
00068     int h = GetBaseHeight();
00069 
00070     if (_pre_layout_width < w)
00071       result |= eLargerWidth;
00072     else if (_pre_layout_width > w)
00073       result |= eSmallerWidth;
00074     else
00075       result |= eCompliantWidth;
00076 
00077     if (_pre_layout_height < h)
00078       result |= eLargerHeight;
00079     else if (_pre_layout_height > h)
00080       result |= eSmallerHeight;
00081     else
00082       result |= eCompliantHeight;
00083 
00084     return result;
00085   }
00086 
00087   long StaticText::ProcessEvent (IEvent& event,
00088     long    traverseInfo,
00089     long    processEventInfo)
00090   {
00091     long ret = traverseInfo;
00092 
00093     ret = PostProcessEvent2 (event, ret, processEventInfo);
00094     return ret;
00095   }
00096 
00097   void StaticText::SetSizeMatchText (bool size_match_text)
00098   {
00099     _size_match_text = size_match_text;
00100   }
00101 
00102   bool StaticText::GetSizeMatchText () const
00103   {
00104     return _size_match_text;
00105   }
00106 
00107   void StaticText::SetClipping (int clipping)
00108   {
00109     if (_clipping == clipping)
00110       return;
00111 
00112     _clipping = clipping;
00113 
00114     if (_clipping < 0)
00115       clipping = 0;
00116 
00117     UpdateTextRendering ();
00118   }
00119 
00120   int StaticText::GetClipping () const
00121   {
00122     return _clipping;
00123   }
00124 
00125   void StaticText::Draw (GraphicsEngine& gfxContext, bool forceDraw)
00126   {
00127     Geometry base = GetGeometry ();
00128 
00129     // Get the current blend states. They will be restored later.
00130     t_u32 alpha = 0, src = 0, dest = 0;
00131     gfxContext.GetRenderStates ().GetBlend (alpha, src, dest);
00132     
00133     gfxContext.GetRenderStates ().SetBlend (true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
00134     
00135     gfxContext.PushClippingRectangle (base);
00136 
00137     TexCoordXForm texxform;
00138     texxform.SetWrap (TEXWRAP_REPEAT, TEXWRAP_REPEAT);
00139     texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
00140 
00141     gfxContext.QRP_1Tex (base.x,
00142       base.y,
00143       base.width,
00144       base.height,
00145       _texture2D->GetDeviceTexture(),
00146       texxform,
00147       _textColor);
00148 
00149     gfxContext.GetRenderStates ().SetBlend (alpha, src, dest);
00150 
00151 
00152     gfxContext.PopClippingRectangle ();
00153   }
00154 
00155   void StaticText::DrawContent (GraphicsEngine& gfxContext, bool forceDraw)
00156   {
00157 
00158   }
00159 
00160   void StaticText::PostDraw (GraphicsEngine& gfxContext, bool forceDraw)
00161   {
00162     // intentionally left empty
00163   }
00164 
00165   void StaticText::SetText (NString text)
00166   {
00167     if (_text != text)
00168     {
00169       _text = text;
00170       UpdateTextRendering ();
00171 
00172       sigTextChanged.emit (this);
00173     }
00174   }
00175 
00176   void StaticText::SetTextColor (Color textColor)
00177   {
00178     if (_textColor != textColor)
00179     {
00180       _textColor = textColor;
00181       sigTextColorChanged.emit (this);
00182     }
00183   }
00184 
00185   void StaticText::SetFontName (const char *font_name)
00186   {
00187     g_free (_font_string);
00188     _font_string = g_strdup (font_name);
00189 
00190     UpdateTextRendering ();
00191     QueueDraw ();
00192   }
00193 
00194   void StaticText::GetTextSize (int &width, int &height, int clipping)
00195   {
00196     GetTextSize (_font_string, _text.GetTCharPtr (), width, height, clipping);
00197   }
00198 
00199   void StaticText::GetTextSize (const TCHAR* font, const TCHAR *char_str, int& width, int& height, int clipping)
00200   {
00201     cairo_surface_t*      surface  = NULL;
00202     cairo_t*              cr       = NULL;
00203     PangoLayout*          layout   = NULL;
00204     PangoFontDescription* desc     = NULL;
00205     PangoContext*         pangoCtx = NULL;
00206     PangoRectangle        logRect  = {0, 0, 0, 0};
00207     int                   dpi      = 96;
00208 
00209     // sanity check
00210     if (!font)
00211       return;
00212 
00213     surface = cairo_image_surface_create (CAIRO_FORMAT_A1, 1, 1);
00214     cr = cairo_create (surface);
00215 
00216     CairoFontOptions font_options;
00217 
00218     cairo_font_options_set_antialias      (font_options, CAIRO_ANTIALIAS_DEFAULT);
00219     cairo_font_options_set_subpixel_order (font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT);
00220     cairo_font_options_set_hint_style     (font_options, CAIRO_HINT_STYLE_DEFAULT);
00221     cairo_font_options_set_hint_metrics   (font_options, CAIRO_HINT_METRICS_ON);
00222 
00223     cairo_set_font_options (cr, font_options);
00224 
00225     layout = pango_cairo_create_layout (cr);
00226     desc = pango_font_description_from_string (font);
00227     pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
00228     pango_layout_set_font_description (layout, desc);
00229     pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
00230     pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
00231     pango_layout_set_markup (layout, char_str, -1);
00232 
00233     if (clipping)
00234       pango_layout_set_width (layout, clipping * PANGO_SCALE);
00235 
00236     pangoCtx = pango_layout_get_context (layout); // is not ref'ed
00237     pango_cairo_context_set_font_options (pangoCtx, font_options);
00238 
00239     // use some default DPI-value
00240     pango_cairo_context_set_resolution (pangoCtx, dpi);
00241 
00242     pango_layout_context_changed (layout);
00243     pango_layout_get_extents (layout, NULL, &logRect);
00244 
00245     width  = logRect.width / PANGO_SCALE;
00246     height = logRect.height / PANGO_SCALE;
00247 
00248     // clean up
00249     pango_font_description_free (desc);
00250     g_object_unref (layout);
00251     cairo_destroy (cr);
00252     cairo_surface_destroy (surface);
00253   }
00254 
00255   void StaticText::DrawText (void* cairo_context, int width, int height, Color color)
00256   {
00257     cairo_t* cr = (cairo_t*) cairo_context;
00258 
00259     int                   textWidth  = 0;
00260     int                   textHeight = 0;
00261     PangoLayout*          layout     = NULL;
00262     PangoFontDescription* desc       = NULL;
00263     PangoContext*         pangoCtx   = NULL;
00264     int                   dpi        = 0;
00265 
00266     GetTextSize (textWidth, textHeight, _clipping);
00267 
00268     CairoFontOptions font_options;
00269 
00270     cairo_font_options_set_antialias      (font_options, CAIRO_ANTIALIAS_DEFAULT);
00271     cairo_font_options_set_subpixel_order (font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT);
00272     cairo_font_options_set_hint_style     (font_options, CAIRO_HINT_STYLE_DEFAULT);
00273     cairo_font_options_set_hint_metrics   (font_options, CAIRO_HINT_METRICS_ON);
00274 
00275     cairo_set_font_options (cr, font_options);
00276 
00277     layout = pango_cairo_create_layout (cr);
00278     desc = pango_font_description_from_string (_font_string);
00279     pango_layout_set_font_description (layout, desc);
00280 
00281     pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
00282     pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
00283     pango_layout_set_markup (layout, _text.GetTCharPtr(), -1);
00284     if (_clipping)
00285       pango_layout_set_width (layout, _clipping * PANGO_SCALE);
00286 
00287     pangoCtx = pango_layout_get_context (layout);
00288     pango_cairo_context_set_font_options (pangoCtx, font_options);
00289 
00290     pango_cairo_context_set_resolution (pangoCtx, dpi);
00291 
00292     cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
00293 
00294     pango_layout_context_changed (layout);
00295 
00296     cairo_move_to (cr, 0.0f, 0.0f);
00297     pango_cairo_show_layout (cr, layout);
00298 
00299     // clean up
00300     pango_font_description_free (desc);
00301     g_object_unref (layout);
00302   }
00303 
00304   void StaticText::UpdateTextRendering ()
00305   {
00306     int width = 0;
00307     int height = 0;
00308     GetTextSize(width, height, _clipping);
00309 
00310     if (GetSizeMatchText () && (width != 0) && (height != 0))
00311     {
00312       SetMinMaxSize (width, height);
00313     }
00314 
00315     _cairoGraphics = new CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
00316     cairo_t *cr = _cairoGraphics->GetContext ();
00317     cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
00318     cairo_paint (cr);
00319     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
00320 
00321     DrawText (cr, GetBaseWidth (), GetBaseHeight (), _textColor);
00322 
00323     NBitmapData* bitmap = _cairoGraphics->GetBitmap ();
00324 
00325     // NTexture2D is the high level representation of an image that is backed by
00326     // an actual opengl texture.
00327 
00328     if (_texture2D)
00329       _texture2D->UnReference ();
00330 
00331     _texture2D = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture ();
00332     _texture2D->Update (bitmap);
00333                 
00334                 delete bitmap;
00335                 cairo_destroy (cr);
00336     delete _cairoGraphics;
00337     _cairoGraphics = 0;
00338   }
00339 
00340 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends