示例#1
0
	void SimpleSurface::applyFilter (Surface *inSrc, const Rect &inRect, ImagePoint inOffset, Filter *inFilter) {
		
		if (!mBase) return;
		FilterList f;
		f.push_back (inFilter);
		
		Rect src_rect (inRect.w, inRect.h);
		Rect dest = GetFilteredObjectRect (f, src_rect);
		
		inSrc->IncRef ();
		Surface *result = FilterBitmap (f, inSrc, src_rect, dest, false, ImagePoint (inRect.x, inRect.y));
		
		dest.Translate (inOffset.x, inOffset.y);
		
		src_rect = Rect (0, 0, result->Width (), result->Height ());
		int dx = dest.x;
		int dy = dest.y;
		dest = dest.Intersect (Rect (0, 0, mWidth, mHeight));
		dest.Translate (-dx, -dy);
		dest = dest.Intersect (src_rect);
		dest.Translate (dx, dy);
		
		int bpp = BytesPP ();
		
		RenderTarget t = BeginRender (dest, false);
		//printf("Copy back @ %d,%d %dx%d  + (%d,%d)\n", dest.x, dest.y, t.Width(), t.Height(), dx, dy);
		for (int y = 0; y < t.Height (); y++)
			memcpy ((void *)(t.Row (y + dest.y) + ((dest.x) * bpp)), result->Row (y - dy) - (dx * bpp), dest.w * bpp);
		
		EndRender ();
		
		result->DecRef ();
		
	}
示例#2
0
文件: FreeType.cpp 项目: nedwidek/NME
    void RenderGlyph(int inChar,const RenderTarget &outTarget)
    {
        if (!LoadBitmap(inChar))
            return;

        FT_Bitmap &bitmap = mFace->glyph->bitmap;
        int w = bitmap.width;
        int h = bitmap.rows;
        if (w>outTarget.mRect.w || h>outTarget.mRect.h)
            return;

        for(int r=0; r<h; r++)
        {
            unsigned char *row = bitmap.buffer + r*bitmap.pitch;
            uint8  *dest = (uint8 *)outTarget.Row(r + outTarget.mRect.y) + outTarget.mRect.x;

            if (bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
            {
                int bit = 0;
                int data = 0;
                for(int x=0; x<outTarget.mRect.w; x++)
                {
                    if (!bit)
                    {
                        bit = 128;
                        data = *row++;
                    }
                    *dest++ =  (data & bit) ? 0xff: 0x00;
                    bit >>= 1;
                }
            }
            else if (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
示例#3
0
	void AlphaMask::RenderBitmap(int inTX, int inTY, const RenderTarget &inTarget, const RenderState &inState)
	{
		if (mLineStarts.size() < 2)
			return;
		
		Rect clip = inState.mClipRect;
		int y = mRect.y + inTY;
		const int *start = &mLineStarts[0] - y;
		
		int y1 = mRect.y1() + inTY;
		clip.ClipY(y, y1);
		
		for (; y < y1; y++)
		{
			const AlphaRun *end = &mAlphaRuns[start[y + 1]];
			const AlphaRun *run = &mAlphaRuns[start[y]];
			
			if (run != end)
			{
				Uint8 *dest0 = inTarget.Row(y);
				while (run < end && run->mX1 + inTX <= clip.x)
					run++;
				
				while (run < end)
				{
					int x0 = run->mX0 + inTX;
					if (x0 >= clip.x1())
						break;
					int x1 = run->mX1 + inTX;
					clip.ClipX(x0, x1);
					
					Uint8 *dest = dest0 + x0;
					int alpha = run->mAlpha;
					
					if (alpha > 0)
					{
						if (alpha >= 255)
						{
							while (x0++ < x1)
								*dest++ = 255;
						}
						else
						{
							while(x0++ < x1)
								QBlendAlpha(*dest++, alpha);
						}
					}
					++run;
				}
			}
		}
		
	}
示例#4
0
文件: FreeType.cpp 项目: AZidan/nme
   void RenderGlyph(int inChar,const RenderTarget &outTarget)
   {
      if (!LoadBitmap(inChar))
         return;

      int underlineY0 = -1;
      int underlineY1 = -1;

      FT_Bitmap &bitmap = mFace->glyph->bitmap;
      int w = bitmap.width;
      int h = bitmap.rows;
 
      if (mTransform & ffUnderline)
      {
         underlineY0 = mFace->glyph->bitmap_top + getUnderlineOffset();
         underlineY1 = underlineY0 + getUnderlineHeight();
      }

      if (h<underlineY1)
         h = underlineY1;

      if (w>outTarget.mRect.w || h>outTarget.mRect.h)
         return;

      for(int r=0;r<h;r++)
      {
         uint8  *dest = (uint8 *)outTarget.Row(r + outTarget.mRect.y) + outTarget.mRect.x;

         int underline = (r>=underlineY0 && r<underlineY1) ? 0xff : 0;

         if (r<bitmap.rows)
         {
            unsigned char *row = bitmap.buffer + r*bitmap.pitch;
            if (bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
            {
               int bit = 0;
               int data = 0;
               for(int x=0;x<outTarget.mRect.w;x++)
               {
                  if (!bit)
                  {
                     bit = 128;
                     data = *row++;
                  }
                  *dest++ =  (underline || (data & bit)) ? 0xff: 0x00;
                  bit >>= 1;
               }
            }
            else if (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
示例#5
0
文件: GDIFont.cpp 项目: gunnbr/lime
   void RenderGlyph(int inChar, const RenderTarget &outTarget)
   {
      if (!sGammaLUTInit)
      {
         double pow_max = 255.0/pow(255,1.9);
         for(int i=0;i<256;i++)
         {
            sGammaLUT[i] = pow(i,1.9)*pow_max + 0.5;
         }
         sGammaLUTInit = true;
      }
      int w = outTarget.mRect.w;
      w = (w+3) & ~3;
      int h = outTarget.mRect.h;
      if (w>sgDIB_W || h>sgDIB_H)
      {
         if (sgDIB)
         {
            SelectObject(sgFontDC,sgOldDIB);
            DeleteObject(sgDIB);
         }
         BITMAPINFO bmi;
         memset(&bmi,0,sizeof(bmi));
         bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
         bmi.bmiHeader.biWidth = w;
         bmi.bmiHeader.biHeight = h;
         bmi.bmiHeader.biPlanes = 1;
         bmi.bmiHeader.biBitCount = 32;
         bmi.bmiHeader.biCompression = BI_RGB;
         sgDIB_W = w;
         sgDIB_H = h;

         sgDIB = CreateDIBSection(sgFontDC,&bmi,DIB_RGB_COLORS, (void **)&sgDIBBits, 0, 0 );
         sgOldDIB = (HBITMAP)SelectObject(sgFontDC,sgDIB);
      }
      memset(sgDIBBits,0,sgDIB_W*sgDIB_H*4);
      wchar_t ch = inChar;
      TextOutW(sgFontDC,0,0,&ch,1);

      for(int y=0;y<outTarget.mRect.h;y++)
      {
         ARGB *src = sgDIBBits + (sgDIB_H - 1 - y)*sgDIB_W;
         uint8  *dest = (uint8 *)outTarget.Row(y + outTarget.mRect.y) + outTarget.mRect.x;
         for(int x=0;x<outTarget.mRect.w;x++)
            *dest++= sGammaLUT[(src++)->g];
      }

   }
示例#6
0
bool PointRenderer::Render( const RenderTarget &inTarget, const RenderState &inState )
{
    Extent2DF extent;
    CachedExtentRenderer::GetExtent(inState.mTransform,extent);

    if (!extent.Valid())
        return true;

    // Get bounding pixel rect
    Rect rect = inState.mTransform.GetTargetRect(extent);

    // Intersect with clip rect ...
    Rect visible_pixels = rect.Intersect(inState.mClipRect);
    int x0 = visible_pixels.x;
    int y0 = visible_pixels.y;
    int x1 = visible_pixels.x1();
    int y1 = visible_pixels.y1();

    bool swap = gC0IsRed != (bool)(inTarget.mPixelFormat & pfSwapRB);
    //bool alpha = (inTarget.mPixelFormat & pfHasAlpha);

    if (!mHasColours)
    {
        int val = swap ? mCol.SwappedIVal() : mCol.ival;
        // 100% alpha...
        if ( ( (val & 0xff000000) == 0xff000000 ) || (inTarget.mPixelFormat & pfHasAlpha) )
        {
            for(int i=0; i<mTransformed.size(); i++)
            {
                const UserPoint &point = mTransformed[i];
                int tx = point.x;
                if (x0<=tx && tx<x1)
                {
                    int ty = point.y;
                    if (y0<=ty && ty<y1)
                        ((int *)inTarget.Row(ty))[tx] = val;
                }
            }
        }
        else
        {
            ARGB argb = swap ? mCol.Swapped() : mCol;

            for(int i=0; i<mTransformed.size(); i++)
            {
                const UserPoint &point = mTransformed[i];
                int tx = point.x;
                if (x0<=tx && tx<x1)
                {
                    int ty = point.y;
                    if (y0<=ty && ty<y1)
                        ((ARGB *)inTarget.Row(ty))[tx].QBlendA(argb);
                }
            }
        }
    }
    else
    {
        ARGB *argb = (ARGB *) & mData[mData0 + mTransformed.size()*2];
        if (inTarget.mPixelFormat & pfHasAlpha)
            for(int i=0; i<mTransformed.size(); i++)
            {
                const UserPoint &point = mTransformed[i];
                int tx = point.x;
                if (x0<=tx && tx<x1)
                {
                    int ty = point.y;
                    if (y0<=ty && ty<y1)
                        ((ARGB *)inTarget.Row(ty))[tx].QBlendA( swap? argb[i] : argb[i].Swapped() );
                }
            }
        else
            for(int i=0; i<mTransformed.size(); i++)
            {
                const UserPoint &point = mTransformed[i];
                int tx = point.x;
                if (x0<=tx && tx<x1)
                {
                    int ty = point.y;
                    if (y0<=ty && ty<y1)
                        ((ARGB *)inTarget.Row(ty))[tx].QBlend( swap? argb[i].Swapped() : argb[i] );
                }
            }
    }

    return true;
}
示例#7
0
	void SimpleSurface::BlitChannel (const RenderTarget &outTarget, const Rect &inSrcRect, int inPosX, int inPosY, int inSrcChannel, int inDestChannel) const {
		
		bool src_alpha = (mPixelFormat == pfAlpha);
		bool dest_alpha = (outTarget.mPixelFormat == pfAlpha);
		
		// Flash API does not have alpha images (might be useful somewhere else?)
		if (src_alpha || dest_alpha)
			return;
		
		if (inDestChannel == CHAN_ALPHA && !(outTarget.Format () & pfHasAlpha))
			return;
		
		bool set_255 = (inSrcChannel == CHAN_ALPHA && !(mPixelFormat & pfHasAlpha));
		
		// Translate inSrcRect src_rect to dest ...
		Rect src_rect (inPosX, inPosY, inSrcRect.w, inSrcRect.h);
		// clip ...
		src_rect = src_rect.Intersect (outTarget.mRect);
		
		// translate back to source-coordinates ...
		src_rect.Translate (inSrcRect.x - inPosX, inSrcRect.y - inPosY);
		// clip to origial rect...
		src_rect = src_rect.Intersect (inSrcRect);
		
		if (src_rect.HasPixels ()) {
			
			int dx = inPosX + src_rect.x;
			int dy = inPosY + src_rect.y;
			
			bool c0_red = gC0IsRed != ((mPixelFormat & pfSwapRB) != 0);
			int src_ch = (inSrcChannel == CHAN_ALPHA ? 3 : inSrcChannel == CHAN_BLUE ? (c0_red ? 2 : 0) : inSrcChannel == CHAN_GREEN ? 1 : (c0_red ? 0 : 2));
			
			c0_red = gC0IsRed != ((outTarget.Format () & pfSwapRB) != 0);
			int dest_ch = (inDestChannel == CHAN_ALPHA ? 3 : inDestChannel == CHAN_BLUE ? (c0_red ? 2 : 0) : inDestChannel == CHAN_GREEN ? 1 : (c0_red ? 0 : 2));
			
			for (int y = 0; y < src_rect.h; y++) {
				
				uint8 *d = outTarget.Row (y + dy) + (dx * 4) + dest_ch;
				if (set_255) {
					
					for (int x = 0; x < src_rect.w; x++) {
						
						*d = 255;
						d += 4;
						
					}
					
				} else {
					
					const uint8 *s = Row (y + src_rect.y) + (src_rect.x * 4) + src_ch;
					
					for(int x = 0; x < src_rect.w; x++) {
						
						*d = *s;
						d += 4;
						s += 4;
						
					}
					
				}
				
			}
			
		}
		
	}
示例#8
0
static Surface *TryPNG(FILE *inFile,const uint8 *inData, int inDataLen)
{
   png_structp png_ptr;
   png_infop info_ptr;
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type;

   /* Create and initialize the png_struct with the desired error handler
    * functions.  If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.  We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.  REQUIRED
    */
   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
      0, user_error_fn, user_warning_fn);

   if (png_ptr == NULL)
      return (0);

   /* Allocate/initialize the memory for image information.  REQUIRED. */
   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL)
   {
      png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
      return (0);
   }

   /* Set error handling if you are using the setjmp/longjmp method (this is
    * the normal method of doing things with libpng).  REQUIRED unless you
    * set up your own error handlers in the png_create_read_struct() earlier.
    */

   Surface *result = 0;
   RenderTarget target;

   if (setjmp(png_jmpbuf(png_ptr)))
   {
      if (result)
      {
         result->EndRender();
         result->DecRef();
      }

      /* Free all of the memory associated with the png_ptr and info_ptr */
      png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
      /* If we get here, we had a problem reading the file */
      return (0);
   }

   ReadBuf buffer(inData,inDataLen);
   if (inFile)
   {
      png_init_io(png_ptr, inFile);
   }
   else
   {
      png_set_read_fn(png_ptr,(void *)&buffer, user_read_data_fn);
   }

   png_read_info(png_ptr, info_ptr);

   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
       &interlace_type, NULL, NULL);

   bool has_alpha = color_type== PNG_COLOR_TYPE_GRAY_ALPHA ||
                    color_type==PNG_COLOR_TYPE_RGB_ALPHA ||
                    png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
   
   /* Add filler (or alpha) byte (before/after each RGB triplet) */
   png_set_expand(png_ptr);
   png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
   //png_set_gray_1_2_4_to_8(png_ptr);
   png_set_palette_to_rgb(png_ptr);
   png_set_gray_to_rgb(png_ptr);

   // Stripping 16 bits per channel to 8 bits per channel.
   if (bit_depth == 16)
      png_set_strip_16(png_ptr);

   png_set_bgr(png_ptr);

   result = new SimpleSurface(width,height, (has_alpha) ? pfARGB : pfXRGB);
   result->IncRef();
   target = result->BeginRender(Rect(width,height));
   
   /* if the image is interlaced, run multiple passes */
   int number_of_passes = png_set_interlace_handling(png_ptr);
   
   for (int pass = 0; pass < number_of_passes; pass++)
   {
      for (int i = 0; i < height; i++)
      {
         png_bytep anAddr = (png_bytep) target.Row(i);
         png_read_rows(png_ptr, (png_bytepp) &anAddr, NULL, 1);
      }
   }

   result->EndRender();

   /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
   png_read_end(png_ptr, info_ptr);

   /* clean up after the read, and free any memory allocated - REQUIRED */
   png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);

   /* that's it */
   return result;
}
示例#9
0
static Surface *TryJPEG(FILE *inFile,const uint8 *inData, int inDataLen)
{
   struct jpeg_decompress_struct cinfo;

   // Don't exit on error!
   struct ErrorData jpegError;
   cinfo.err = jpeg_std_error(&jpegError.base);
   jpegError.base.error_exit = OnError;
   jpegError.base.output_message = OnOutput;

   Surface *result = 0;
   uint8 *row_buf = 0;

   // Establish the setjmp return context for ErrorFunction to use
   if (setjmp(jpegError.on_error))
   {
      if (row_buf)
         free(row_buf);
      if (result)
         result->DecRef();

      jpeg_destroy_decompress(&cinfo);
      return 0;
   }

   // Initialize the JPEG decompression object.
   jpeg_create_decompress(&cinfo);

   // Specify data source (ie, a file, or buffer)
   MySrcManager manager(inData,inDataLen);
   if (inFile)
      jpeg_stdio_src(&cinfo, inFile);
   else
   {
      cinfo.src = &manager.pub;
   }

   // Read file parameters with jpeg_read_header().
   if (jpeg_read_header(&cinfo, TRUE)!=JPEG_HEADER_OK)
      return 0;

   cinfo.out_color_space = JCS_RGB;

   // Start decompressor.
   jpeg_start_decompress(&cinfo);

   result = new SimpleSurface(cinfo.output_width, cinfo.output_height, pfXRGB);
   result->IncRef();


   RenderTarget target = result->BeginRender(Rect(cinfo.output_width, cinfo.output_height));


   row_buf = (uint8 *)malloc(cinfo.output_width * 3);

   while (cinfo.output_scanline < cinfo.output_height)
   {
      uint8 * src = row_buf;
      uint8 * dest = target.Row(cinfo.output_scanline);

      jpeg_read_scanlines(&cinfo, &row_buf, 1);

      uint8 *end = dest + cinfo.output_width*4;
      while (dest<end)
      {
         dest[0] = src[2];
         dest[1] = src[1];
         dest[2] = src[0];
         dest[3] = 0xff;
         dest+=4;
         src+=3;
      }
   }
   result->EndRender();

   free(row_buf);

   // Finish decompression.
   jpeg_finish_decompress(&cinfo);

   // Release JPEG decompression object
   jpeg_destroy_decompress(&cinfo);

   return result;
}
示例#10
0
Tile Font::GetGlyph(int inCharacter,int &outAdvance)
{
   bool use_default = false;
   Glyph &glyph = inCharacter < 128 ? mGlyph[inCharacter] : mExtendedGlyph[inCharacter];
   if (glyph.sheet<0)
   {
      int gw,gh,adv,ox,oy;
      bool ok = mFace->GetGlyphInfo(inCharacter,gw,gh,adv,ox,oy);
      if (!ok)
      {
         if (inCharacter=='?')
         {
            gw = mPixelHeight;
            gh = mPixelHeight;
            ox = oy = 0;
            adv = mPixelHeight;
            use_default = true;
         }
         else
         {
            Tile result = GetGlyph('?',outAdvance);
            glyph = mGlyph['?'];
            return result;
         }
      }

      int orig_w = gw;
      int orig_h = gh;
      switch(mRotation)
      {
         case gr270:
            std::swap(gw,gh);
            std::swap(ox,oy);
            oy = -gh-oy;
            break;
         case gr180:
            ox = -gw-ox;
            oy = -gh-oy;
            break;
         case gr90:
            std::swap(gw,gh);
            std::swap(ox,oy);
            ox = -gw-ox;
            break;
      }


      while(1)
      {
         // Allocate new sheet?
         if (mCurrentSheet<0)
         {
            int rows = mPixelHeight > 128 ? 1 : mPixelHeight > 64 ? 2 : mPixelHeight>32 ? 4 : 5;
            int h = 4;
            while(h<mPixelHeight*rows)
               h*=2;
            int w = h;
            while(w<orig_w)
               w*=2;
            if (mRotation!=gr0 && mRotation!=gr180)
               std::swap(w,h);
            Tilesheet *sheet = new Tilesheet(w,h,pfAlpha,true);
            mCurrentSheet = mSheets.size();
            mSheets.push_back(sheet);
         }

         int tid = mSheets[mCurrentSheet]->AllocRect(gw,gh,ox,oy);
         if (tid>=0)
         {
            glyph.sheet = mCurrentSheet;
            glyph.tile = tid;
            glyph.advance = adv;
            break;
         }

         // Need new sheet...
         mCurrentSheet = -1;
      }
      // Now fill rect...
      Tile tile = mSheets[glyph.sheet]->GetTile(glyph.tile);
      // SharpenText(bitmap);
      RenderTarget target = tile.mSurface->BeginRender(tile.mRect);
      if (use_default)
      {
         for(int y=0; y<target.mRect.h; y++)
         {
            uint8  *dest = (uint8 *)target.Row(y + target.mRect.y) + target.mRect.x;
            for(int x=0; x<target.mRect.w; x++)
               *dest++ = 0xff;
         }
      }
      else if (mRotation==gr0)
         mFace->RenderGlyph(inCharacter,target);
      else
      {
         SimpleSurface *buf = new SimpleSurface(orig_w,orig_h,pfAlpha,true);
         buf->IncRef();
         {
         AutoSurfaceRender renderer(buf);
         mFace->RenderGlyph(inCharacter,renderer.Target());
         }

         const uint8  *src;
         for(int y=0; y<target.mRect.h; y++)
         {
            uint8  *dest = (uint8 *)target.Row(y + target.mRect.y) + target.mRect.x;

            switch(mRotation)
            {
               case gr270:
                  src = buf->Row(0) + buf->Width() -1 - y;
                  for(int x=0; x<target.mRect.w; x++)
                  {
                     *dest++ = *src;
                     src += buf->GetStride();
                  }
                  break;
               case gr180:
                  src = buf->Row(buf->Height()-1-y) + buf->Width() -1;
                  for(int x=0; x<target.mRect.w; x++)
                     *dest++ = *src--;
                  break;
               case gr90:
                  src = buf->Row(buf->Height()-1) + y;
                  for(int x=0; x<target.mRect.w; x++)
                  {
                     *dest++ = *src;
                     src -= buf->GetStride();
                  }
                  break;
            }
         }
         buf->DecRef();
      }

      tile.mSurface->EndRender();
      outAdvance = glyph.advance;
      return tile;
   }

   outAdvance = glyph.advance;
   return mSheets[glyph.sheet]->GetTile(glyph.tile);
}