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; } }
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); }