root/native_client_sdk/src/examples/demo/flock/sprite.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. Blend
  2. SetPixelBuffer
  3. CompositeFromRectToPoint

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>

#include "sprite.h"

namespace {

inline uint32_t Blend(uint32_t src1, uint32_t src2) {
  // Divide both sources by 2, then add them together using a mask
  // to avoid overflow.
  src1 = (src1 >> 1) & 0x7F7F7F7F;
  src2 = (src2 >> 1) & 0x7F7F7F7F;
  return src1 + src2;
}

}  // namespace


Sprite::Sprite(uint32_t* pixel_buffer,
               const pp::Size& size,
               int32_t row_bytes) {
  SetPixelBuffer(pixel_buffer, size, row_bytes);
}

Sprite::~Sprite() {
  delete[] pixel_buffer_;
}

void Sprite::SetPixelBuffer(uint32_t* pixel_buffer,
                            const pp::Size& size,
                            int32_t row_bytes) {
  pixel_buffer_ = pixel_buffer;
  pixel_buffer_size_ = size;
  row_bytes_ = row_bytes ? row_bytes : size.width() * sizeof(uint32_t);
}

void Sprite::CompositeFromRectToPoint(const pp::Rect& src_rect,
                                      uint32_t* dest_pixel_buffer,
                                      const pp::Rect& dest_bounds,
                                      int32_t dest_row_bytes,
                                      const pp::Point& dest_point) const {
  // Clip the source rect to the source image bounds.
  pp::Rect src_bounds(pp::Point(), size());
  pp::Rect src_rect_clipped(src_rect.Intersect(src_bounds));
  if (src_rect_clipped.IsEmpty())
    return;

  // Create a clipped rect in the destination coordinate space that contains the
  // final image.
  pp::Rect draw_rect(dest_point, src_rect_clipped.size());
  pp::Rect draw_rect_clipped(dest_bounds.Intersect(draw_rect));
  if (draw_rect_clipped.IsEmpty())
    return;
  // Transform the dest rect to the source image coordinate system.
  pp::Point src_offset(draw_rect_clipped.point());
  src_offset -= dest_point;
  src_rect_clipped.Offset(src_offset);
  src_rect_clipped.set_size(draw_rect_clipped.size());
  size_t src_byte_offset = src_rect_clipped.x() * sizeof(uint32_t) +
                           src_rect_clipped.y() * row_bytes_;
  const uint8_t* src_pixels =
      reinterpret_cast<const uint8_t*>(pixel_buffer_) + src_byte_offset;

  if (dest_row_bytes == 0)
    dest_row_bytes = dest_bounds.width() * sizeof(uint32_t);
  size_t dest_byte_offset = draw_rect_clipped.point().x() * sizeof(uint32_t) +
                            draw_rect_clipped.point().y() * dest_row_bytes;
  uint8_t* dest_pixels = reinterpret_cast<uint8_t*>(dest_pixel_buffer) +
                         dest_byte_offset;

  for (int32_t y = 0; y < src_rect_clipped.height(); ++y) {
    const uint32_t* src_scanline =
        reinterpret_cast<const uint32_t*>(src_pixels);
    uint32_t* dest_scanline = reinterpret_cast<uint32_t*>(dest_pixels);
    for (int32_t x = 0; x < src_rect_clipped.width(); ++x) {
      uint32_t src = *src_scanline++;
      uint32_t dst = *dest_scanline;
      *dest_scanline++ = Blend(dst, src);
    }
    src_pixels += row_bytes_;
    dest_pixels += dest_row_bytes;
  }
}


/* [<][>][^][v][top][bottom][index][help] */