static void MaleTestbild(BitmapContext bmpTarget, BitmapContext bmpSource, int px, int py, BildElement bildElement, BildTeile bildTeile = BildTeile.Alle)
    {
      var target = new RectInt(px * BoxPixelWidth * Multi, py * BoxPixelHeight * Multi, BoxPixelWidth * Multi, BoxPixelHeight * Multi);
      int elY = (int)bildElement / 7;
      int elX = (int)bildElement - (elY * 7);
      var source = new RectInt(elX * BoxPixelWidth, elY * BoxPixelHeight, BoxPixelWidth, BoxPixelHeight);

      switch (bildTeile)
      {
        case BildTeile.Alle: break;
        case BildTeile.Links: target.w /= 2; source.w /= 2; break;
        case BildTeile.Rechts: target.w /= 2; source.w /= 2; target.x += BoxPixelWidth * Multi / 2; source.x += BoxPixelWidth / 2; break;
        case BildTeile.Oben: target.h /= 2; source.h /= 2; break;
        case BildTeile.Unten: target.h /= 2; source.h /= 2; target.y += BoxPixelHeight * Multi / 2; source.y += BoxPixelHeight / 2; break;
        case BildTeile.LinksOben: target.w /= 2; target.h /= 2; source.w /= 2; source.h /= 2; break;
        case BildTeile.RechtsOben: target.w /= 2; target.h /= 2; source.w /= 2; source.h /= 2; target.x += BoxPixelWidth * Multi / 2; source.x += BoxPixelWidth / 2; break;
        case BildTeile.LinksUnten: target.w /= 2; target.h /= 2; source.w /= 2; source.h /= 2; target.y += BoxPixelHeight * Multi / 2; source.y += BoxPixelHeight / 2; break;
        case BildTeile.RechtsUnten: target.w /= 2; target.h /= 2; source.w /= 2; source.h /= 2; target.x += BoxPixelWidth * Multi / 2; source.x += BoxPixelWidth / 2; target.y += BoxPixelHeight * Multi / 2; source.y += BoxPixelHeight / 2; break;
        default: throw new Exception("kombi unbekannt: " + (int)bildTeile);
      }

      if (bildElement == BildElement.Frei)
      {
        bmpTarget.FillRectangle(target.x, target.y, target.x + target.w, target.y + target.h, 0x001122);
      }

      bmpTarget.Blit(target, bmpSource, source, Colors.White, BlendMode.Alpha);
    }
 /// <summary>
 /// Creates a new cropped WriteableBitmap.
 /// </summary>
 /// <param name="context">The WriteableBitmap.</param>
 /// <param name="region">The rectangle that defines the crop region.</param>
 /// <returns>A new WriteableBitmap that is a cropped version of the input.</returns>
 public static WriteableBitmap Crop(this BitmapContext context, RectInt region)
 {
   return context.Crop(region.x, region.y, region.w, region.h);
 }
 public static RectInt Intersect(RectInt a, RectInt b)
 {
   int x = Math.Max(a.x, b.x);
   int num1 = Math.Min(a.x + a.w, b.x + b.w);
   int y = Math.Max(a.y, b.y);
   int num2 = Math.Min(a.y + a.h, b.y + b.h);
   if (num1 >= x && num2 >= y) return new RectInt(x, y, num1 - x, num2 - y);
   return Empty;
 }
    /// <summary>
    /// Copies (blits) the pixels from the WriteableBitmap source to the destination WriteableBitmap (this).
    /// </summary>
    /// <param name="destContext">The destination WriteableBitmap.</param>
    /// <param name="destRect">The rectangle that defines the destination region.</param>
    /// <param name="srcContext">The source WriteableBitmap.</param>
    /// <param name="sourceRect">The rectangle that will be copied from the source to the destination.</param>
    /// <param name="color">If not Colors.White, will tint the source image. A partially transparent color and the image will be drawn partially transparent. If the BlendMode is ColorKeying, this color will be used as color key to mask all pixels with this value out.</param>
    /// <param name="blendMode">The blending mode <see cref="BlendMode"/>.</param>
    public static void Blit(this BitmapContext destContext, RectInt destRect, BitmapContext srcContext, RectInt sourceRect, Color color, BlendMode blendMode)
    {
      if (color.A == 0)
      {
        return;
      }
      int dw = destRect.w;
      int dh = destRect.h;

      int sourceWidth = srcContext.Width;
      int dpw = destContext.Width;
      int dph = destContext.Height;
      var intersect = RectInt.Intersect(new RectInt(0, 0, dpw, dph), destRect);
      if (intersect.IsEmpty)
      {
        return;
      }

      var sourcePixels = srcContext.Pixels;
      var destPixels = destContext.Pixels;
      int sourceLength = srcContext.Length;
      int px = destRect.x;
      int py = destRect.y;
      int y;
      double jj;
      int sr = 0;
      int sg = 0;
      int sb = 0;
      int sa = 0;
      int ca = color.A;
      int cr = color.R;
      int cg = color.G;
      int cb = color.B;
      bool tinted = color != Colors.White;
      var sw = sourceRect.w;
      var sdx = sourceRect.w / (double)destRect.w;
      var sdy = sourceRect.h / (double)destRect.h;
      int sourceStartX = sourceRect.x;
      int sourceStartY = sourceRect.y;
      int lastii, lastjj;
      lastii = -1;
      lastjj = -1;
      jj = sourceStartY;
      y = py;
      for (int j = 0; j < dh; j++)
      {
        if (y >= 0 && y < dph)
        {
          double ii = sourceStartX;
          var idx = px + y * dpw;
          var x = px;
          var sourcePixel = sourcePixels[0];

          // Scanline BlockCopy is much faster (3.5x) if no tinting and blending is needed,
          // even for smaller sprites like the 32x32 particles. 
          int sourceIdx;
          if (blendMode == BlendMode.None && !tinted)
          {
            sourceIdx = (int)ii + (int)jj * sourceWidth;
            var offset = x < 0 ? -x : 0;
            var xx = x + offset;
            var wx = sourceWidth - offset;
            var len = xx + wx < dpw ? wx : dpw - xx;
            if (len > sw) len = sw;
            if (len > dw) len = dw;
            BitmapContext.BlockCopy(srcContext, (sourceIdx + offset) * 4, destContext, (idx + offset) * 4, len * 4);
          }

          // Pixel by pixel copying
          else
          {
            for (int i = 0; i < dw; i++)
            {
              if (x >= 0 && x < dpw)
              {
                if ((int)ii != lastii || (int)jj != lastjj)
                {
                  sourceIdx = (int)ii + (int)jj * sourceWidth;
                  if (sourceIdx >= 0 && sourceIdx < sourceLength)
                  {
                    sourcePixel = sourcePixels[sourceIdx];
                    sa = ((sourcePixel >> 24) & 0xff);
                    sr = ((sourcePixel >> 16) & 0xff);
                    sg = ((sourcePixel >> 8) & 0xff);
                    sb = ((sourcePixel) & 0xff);
                    if (tinted && sa != 0)
                    {
                      sa = (((sa * ca) * 0x8081) >> 23);
                      sr = ((((((sr * cr) * 0x8081) >> 23) * ca) * 0x8081) >> 23);
                      sg = ((((((sg * cg) * 0x8081) >> 23) * ca) * 0x8081) >> 23);
                      sb = ((((((sb * cb) * 0x8081) >> 23) * ca) * 0x8081) >> 23);
                      sourcePixel = (sa << 24) | (sr << 16) | (sg << 8) | sb;
                    }
                  }
                  else
                  {
                    sa = 0;
                  }
                }
                if (blendMode == BlendMode.None)
                {
                  destPixels[idx] = sourcePixel;
                }
                else if (blendMode == BlendMode.ColorKeying)
                {
                  sr = ((sourcePixel >> 16) & 0xff);
                  sg = ((sourcePixel >> 8) & 0xff);
                  sb = ((sourcePixel) & 0xff);

                  if (sr != color.R || sg != color.G || sb != color.B)
                  {
                    destPixels[idx] = sourcePixel;
                  }

                }
                else
                {
                  int dr;
                  int dg;
                  int db;
                  int da;
                  if (blendMode == BlendMode.Mask)
                  {
                    int destPixel = destPixels[idx];
                    da = ((destPixel >> 24) & 0xff);
                    dr = ((destPixel >> 16) & 0xff);
                    dg = ((destPixel >> 8) & 0xff);
                    db = ((destPixel) & 0xff);
                    destPixel = ((((da * sa) * 0x8081) >> 23) << 24) |
                                ((((dr * sa) * 0x8081) >> 23) << 16) |
                                ((((dg * sa) * 0x8081) >> 23) << 8) |
                                ((((db * sa) * 0x8081) >> 23));
                    destPixels[idx] = destPixel;
                  }
                  else if (sa > 0)
                  {
                    int destPixel = destPixels[idx];
                    da = ((destPixel >> 24) & 0xff);
                    if ((sa == 255 || da == 0) &&
                        blendMode != BlendMode.Additive
                        && blendMode != BlendMode.Subtractive
                        && blendMode != BlendMode.Multiply
                      )
                    {
                      destPixels[idx] = sourcePixel;
                    }
                    else
                    {
                      dr = ((destPixel >> 16) & 0xff);
                      dg = ((destPixel >> 8) & 0xff);
                      db = ((destPixel) & 0xff);
                      if (blendMode == BlendMode.Alpha)
                      {
                        destPixel = ((sa + (((da * (255 - sa)) * 0x8081) >> 23)) << 24) |
                                    ((sr + (((dr * (255 - sa)) * 0x8081) >> 23)) << 16) |
                                    ((sg + (((dg * (255 - sa)) * 0x8081) >> 23)) << 8) |
                                    ((sb + (((db * (255 - sa)) * 0x8081) >> 23)));
                      }
                      else if (blendMode == BlendMode.Additive)
                      {
                        int a = (255 <= sa + da) ? 255 : (sa + da);
                        destPixel = (a << 24) |
                                    (((a <= sr + dr) ? a : (sr + dr)) << 16) |
                                    (((a <= sg + dg) ? a : (sg + dg)) << 8) |
                                    (((a <= sb + db) ? a : (sb + db)));
                      }
                      else if (blendMode == BlendMode.Subtractive)
                      {
                        int a = da;
                        destPixel = (a << 24) |
                                    (((sr >= dr) ? 0 : (sr - dr)) << 16) |
                                    (((sg >= dg) ? 0 : (sg - dg)) << 8) |
                                    (((sb >= db) ? 0 : (sb - db)));
                      }
                      else if (blendMode == BlendMode.Multiply)
                      {
                        // Faster than a division like (s * d) / 255 are 2 shifts and 2 adds
                        int ta = (sa * da) + 128;
                        int tr = (sr * dr) + 128;
                        int tg = (sg * dg) + 128;
                        int tb = (sb * db) + 128;

                        int ba = ((ta >> 8) + ta) >> 8;
                        int br = ((tr >> 8) + tr) >> 8;
                        int bg = ((tg >> 8) + tg) >> 8;
                        int bb = ((tb >> 8) + tb) >> 8;

                        destPixel = (ba << 24) |
                                    ((ba <= br ? ba : br) << 16) |
                                    ((ba <= bg ? ba : bg) << 8) |
                                    ((ba <= bb ? ba : bb));
                      }

                      destPixels[idx] = destPixel;
                    }
                  }
                }
              }
              x++;
              idx++;
              ii += sdx;
            }
          }
        }
        jj += sdy;
        y++;
      }
    }
 /// <summary>
 /// Copies (blits) the pixels from the WriteableBitmap source to the destination WriteableBitmap (this).
 /// </summary>
 /// <param name="context">The destination WriteableBitmap.</param>
 /// <param name="destPosition">The destination position in the destination bitmap.</param>
 /// <param name="source">The source WriteableBitmap.</param>
 /// <param name="sourceRect">The rectangle that will be copied from the source to the destination.</param>
 /// <param name="color">If not Colors.White, will tint the source image. A partially transparent color and the image will be drawn partially transparent.</param>
 /// <param name="blendMode">The blending mode <see cref="BlendMode"/>.</param>
 public static void Blit(this BitmapContext context, PointInt destPosition, BitmapContext source, RectInt sourceRect, Color color, BlendMode blendMode)
 {
   var destRect = new RectInt(destPosition, new SizeInt(sourceRect.w, sourceRect.h));
   Blit(context, destRect, source, sourceRect, color, blendMode);
 }
 /// <summary>
 /// Copies (blits) the pixels from the WriteableBitmap source to the destination WriteableBitmap (this).
 /// </summary>
 /// <param name="context">The destination WriteableBitmap.</param>
 /// <param name="destRect">The rectangle that defines the destination region.</param>
 /// <param name="source">The source WriteableBitmap.</param>
 /// <param name="sourceRect">The rectangle that will be copied from the source to the destination.</param>
 public static void Blit(this BitmapContext context, RectInt destRect, BitmapContext source, RectInt sourceRect)
 {
   Blit(context, destRect, source, sourceRect, Colors.White, BlendMode.Alpha);
 }