Ejemplo n.º 1
0
	void SimpleSurface::BlitTo (const RenderTarget &outDest, const Rect &inSrcRect, int inPosX, int inPosY, BlendMode inBlend, const BitmapCache *inMask, uint32 inTint) const {
		
		if (!mBase)
			return;
		
		// Translate inSrcRect src_rect to dest ...
		Rect src_rect (inPosX, inPosY, inSrcRect.w, inSrcRect.h);
		// clip ...
		src_rect = src_rect.Intersect (outDest.mRect);
		
		if (inMask)
			src_rect = src_rect.Intersect (inMask->GetRect ());
		
		// 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 ()) {
			
			bool src_alpha = (mPixelFormat == pfAlpha);
			bool dest_alpha = (outDest.mPixelFormat == pfAlpha);
			
			int dx = inPosX + src_rect.x - inSrcRect.x;
			int dy = inPosY + src_rect.y - inSrcRect.y;
			
			// Check for overlap....
			if (src_alpha == dest_alpha) {
				
				int size_shift = (!src_alpha ? 2 : 0);   //fix for IDX8
				int d_base = (outDest.mSoftPtr - mBase);
				int y_off = d_base / mStride;
				int x_off = (d_base - y_off * mStride) >> size_shift;
				Rect dr (dx + x_off, dy + y_off, src_rect.w, src_rect.h);
				if (src_rect.Intersect (dr).HasPixels ()) {
					
					SimpleSurface sub (src_rect.w, src_rect.h, mPixelFormat);
					Rect sub_dest (0, 0, src_rect.w, src_rect.h);
					
					for (int y = 0; y < src_rect.h; y++)
						memcpy ((void *)sub.Row (y), Row (src_rect.y + y) + (src_rect.x << size_shift), src_rect.w << size_shift);
					
					sub.BlitTo (outDest, sub_dest, dx, dy, inBlend, 0, inTint);
					return;
					
				}
				
			}
Ejemplo n.º 2
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);
}