| 636 | } |
| 637 | #elif defined( CINDER_MAC) || defined( CINDER_MSW_DESKTOP ) || defined( CINDER_ANDROID ) || defined( CINDER_LINUX ) |
| 638 | Surface renderString( const string &str, const Font &font, const ColorA &color, float *baselineOffset ) |
| 639 | { |
| 640 | Line line; |
| 641 | line.addRun( Run( str, font, color ) ); |
| 642 | line.mJustification = Line::LEFT; |
| 643 | line.mLeadingOffset = 0; |
| 644 | line.calcExtents(); |
| 645 | |
| 646 | float totalWidth = line.mWidth; |
| 647 | float totalHeight = line.mHeight; |
| 648 | int pixelWidth = (int)math<float>::ceil( totalWidth ); |
| 649 | int pixelHeight = (int)math<float>::ceil( totalHeight ); |
| 650 | |
| 651 | // Odd failure - return a NULL Surface |
| 652 | if( ( pixelWidth < 0 ) || ( pixelHeight < 0 ) ) |
| 653 | return Surface(); |
| 654 | |
| 655 | #if defined( CINDER_MAC ) |
| 656 | Surface result( pixelWidth, pixelHeight, true, SurfaceChannelOrder::RGBA ); |
| 657 | ::CGContextRef cgContext = cocoa::createCgBitmapContext( result ); |
| 658 | ip::fill( &result, ColorA( 0, 0, 0, 0 ) ); |
| 659 | |
| 660 | float currentY = totalHeight + 1.0f; |
| 661 | currentY -= line.mAscent + line.mLeadingOffset; |
| 662 | line.render( cgContext, currentY, (float)0, pixelWidth ); |
| 663 | |
| 664 | // force all the rendering to finish and release the context |
| 665 | ::CGContextFlush( cgContext ); |
| 666 | ::CGContextRelease( cgContext ); |
| 667 | |
| 668 | ip::unpremultiply( &result ); |
| 669 | #elif defined( CINDER_MSW_DESKTOP ) |
| 670 | // I don't have a great explanation for this other than it seems to be necessary |
| 671 | pixelHeight += 1; |
| 672 | // prep our GDI and GDI+ resources |
| 673 | ::HDC dc = TextManager::instance()->getDc(); |
| 674 | Surface result( pixelWidth, pixelHeight, true, SurfaceConstraintsGdiPlus() ); |
| 675 | Gdiplus::Bitmap *offscreenBitmap = msw::createGdiplusBitmap( result ); |
| 676 | //Gdiplus::Bitmap *offscreenBitmap = new Gdiplus::Bitmap( pixelWidth, pixelHeight, (premultiplied) ? PixelFormat32bppPARGB : PixelFormat32bppARGB ); |
| 677 | Gdiplus::Graphics *offscreenGraphics = Gdiplus::Graphics::FromImage( offscreenBitmap ); |
| 678 | // high quality text rendering |
| 679 | offscreenGraphics->SetTextRenderingHint( Gdiplus::TextRenderingHintAntiAlias ); |
| 680 | // fill the surface with the background color |
| 681 | offscreenGraphics->Clear( Gdiplus::Color( (BYTE)(0), (BYTE)(0), |
| 682 | (BYTE)(0), (BYTE)(0) ) ); |
| 683 | |
| 684 | // walk the lines and render them, advancing our Y offset along the way |
| 685 | float currentY = 0; |
| 686 | currentY += line.mLeadingOffset + line.mLeading; |
| 687 | line.render( offscreenGraphics, currentY, (float)0, (float)pixelWidth ); |
| 688 | |
| 689 | ::GdiFlush(); |
| 690 | |
| 691 | delete offscreenBitmap; |
| 692 | delete offscreenGraphics; |
| 693 | #elif defined( CINDER_ANDROID ) || defined( CINDER_LINUX ) |
| 694 | Surface result = Surface( pixelWidth, pixelHeight, true, SurfaceConstraintsDefault() ); |
| 695 | ip::fill( &result, ColorA( 0, 0, 0, 0 ) ); |
no test coverage detected