コード例 #1
0
void CompoundUpdateInputVisitor::_updateZoom( const Compound* compound,
                                              Frame* frame,
                                              const Frame* outputFrame )
{
    Zoom zoom = frame->getNativeZoom();
    if( !zoom.isValid( )) // if zoom is not set, inherit from parent
        zoom = compound->getInheritZoom();

    // Zoom difference between output and input
    const FrameData* frameData = outputFrame->getMasterData();
    zoom /= frameData->getZoom();

    frame->setZoom( zoom );
}
コード例 #2
0
ファイル: render.cpp プロジェクト: vmrob/aseprite
static void merge_zoomed_image(Image* dst, const Image* src, const Palette* pal,
  int x, int y, int opacity, int blend_mode, Zoom zoom)
{
  if (zoom.scale() >= 1.0)
    merge_zoomed_image_scale_up<DstTraits, SrcTraits>(dst, src, pal, x, y, opacity, blend_mode, zoom);
  else
    merge_zoomed_image_scale_down<DstTraits, SrcTraits>(dst, src, pal, x, y, opacity, blend_mode, zoom);
}
コード例 #3
0
ファイル: Engine.cpp プロジェクト: aib/glito
void
Engine::iterBuildPoints( const Skeleton& skelet, const Zoom& zoom,
			Image& image, const int imax ) const {
    if ( Function::system == LINEAR ) {
	for ( int i = 1; i <= imax; ++i ) {
	    skelet.nextPoint( _x, _y, _color );
	    zoom.toScreen( _x, _y );
	    image.mem_plot( zoom.screenX, zoom.screenY );
	    image.mem_coul( zoom.screenX, zoom.screenY, _color );
	}
    } else if ( Function::system == FORMULA || Function::system == SINUSOIDAL ) {
	// since initial conditions are important, we have to give a new seed to the orbit
	_x = (float)rand()*2/RAND_MAX - 1;
	_y = (float)rand()*2/RAND_MAX - 1;
	skelet.setXY( _x, _y, _color ); // put the seed in the orbit
	for ( int i = 1; i <= imax; ++i ) {
	    skelet.nextPoint( _x, _y, _color );
	    zoom.toScreen( _x, _y );
	    image.mem_plot( zoom.screenX, zoom.screenY );
	    image.mem_coul( zoom.screenX, zoom.screenY, _color );
	    if ( i % 1000 == 0 ) {
		_x = (float)rand()*2/RAND_MAX - 1;
		_y = (float)rand()*2/RAND_MAX - 1;
		skelet.setXY( _x, _y, _color );
	    }
	}
    } else { // JULIA
	Julia& j = zoom.julia;
	for ( int i = 1; i <= imax; ++i ) {
	    skelet.nextPoint( _x, _y, _color );
	    zoom.toScreen( _x, _y );
	    j.handle( _x, _y, image.getHit( zoom.screenX, zoom.screenY ) );
	    image.mem_plot( zoom.screenX, zoom.screenY );
	    image.mem_coul( zoom.screenX, zoom.screenY, _color );
	}
    }
}
コード例 #4
0
ファイル: render.cpp プロジェクト: vmrob/aseprite
void RenderEngine::renderLayer(
  const Layer* layer,
  Image *image,
  int source_x, int source_y,
  FrameNumber frame, Zoom zoom,
  void (*zoomed_func)(Image*, const Image*, const Palette*, int, int, int, int, Zoom),
  bool render_background,
  bool render_transparent,
  int blend_mode)
{
  // we can't read from this layer
  if (!layer->isVisible())
    return;

  switch (layer->type()) {

    case ObjectType::LayerImage: {
      if ((!render_background  &&  layer->isBackground()) ||
          (!render_transparent && !layer->isBackground()))
        break;

      const Cel* cel = static_cast<const LayerImage*>(layer)->getCel(frame);
      if (cel != NULL) {
        Image* src_image;

        // Is the 'preview_image' set to be used with this layer?
        if ((selected_layer == layer) &&
            (selected_frame == frame) &&
            (preview_image != NULL)) {
          src_image = preview_image;
        }
        // If not, we use the original cel-image from the images' stock
        else {
          src_image = cel->image();
        }

        if (src_image) {
          int t, output_opacity;

          output_opacity = MID(0, cel->opacity(), 255);
          output_opacity = INT_MULT(output_opacity, global_opacity, t);

          ASSERT(src_image->maskColor() == m_sprite->transparentColor());

          (*zoomed_func)(image, src_image, m_sprite->getPalette(frame),
            zoom.apply(cel->x()) - source_x,
            zoom.apply(cel->y()) - source_y,
            output_opacity,
            (blend_mode < 0 ?
              static_cast<const LayerImage*>(layer)->getBlendMode():
              blend_mode),
            zoom);
        }
      }
      break;
    }

    case ObjectType::LayerFolder: {
      LayerConstIterator it = static_cast<const LayerFolder*>(layer)->getLayerBegin();
      LayerConstIterator end = static_cast<const LayerFolder*>(layer)->getLayerEnd();

      for (; it != end; ++it) {
        renderLayer(*it, image,
          source_x, source_y,
          frame, zoom, zoomed_func,
          render_background,
          render_transparent,
          blend_mode);
      }
      break;
    }

  }

  // Draw extras
  if (m_document->getExtraCel() &&
      layer == m_currentLayer &&
      frame == m_currentFrame) {
    Cel* extraCel = m_document->getExtraCel();
    if (extraCel->opacity() > 0) {
      Image* extraImage = m_document->getExtraCelImage();

      (*zoomed_func)(image, extraImage, m_sprite->getPalette(frame),
        zoom.apply(extraCel->x()) - source_x,
        zoom.apply(extraCel->y()) - source_y,
        extraCel->opacity(),
        m_document->getExtraCelBlendMode(), zoom);
    }
  }
}
コード例 #5
0
ファイル: render.cpp プロジェクト: vmrob/aseprite
// static
void RenderEngine::renderCheckedBackground(Image* image,
                                           int source_x, int source_y,
                                           Zoom zoom)
{
  int x, y, u, v;
  int tile_w = 16;
  int tile_h = 16;
  int c1 = color_utils::color_for_image(checked_bg_color1, image->pixelFormat());
  int c2 = color_utils::color_for_image(checked_bg_color2, image->pixelFormat());

  switch (checked_bg_type) {

    case CHECKED_BG_16X16:
      tile_w = 16;
      tile_h = 16;
      break;

    case CHECKED_BG_8X8:
      tile_w = 8;
      tile_h = 8;
      break;

    case CHECKED_BG_4X4:
      tile_w = 4;
      tile_h = 4;
      break;

    case CHECKED_BG_2X2:
      tile_w = 2;
      tile_h = 2;
      break;

  }

  if (checked_bg_zoom) {
    tile_w = zoom.apply(tile_w);
    tile_h = zoom.apply(tile_h);
  }

  // Tile size
  if (tile_w < zoom.apply(1)) tile_w = zoom.apply(1);
  if (tile_h < zoom.apply(1)) tile_h = zoom.apply(1);

  if (tile_w < 1) tile_w = 1;
  if (tile_h < 1) tile_h = 1;

  // Tile position (u,v) is the number of tile we start in (source_x,source_y) coordinate
  u = (source_x / tile_w);
  v = (source_y / tile_h);

  // Position where we start drawing the first tile in "image"
  int x_start = -(source_x % tile_w);
  int y_start = -(source_y % tile_h);

  // Draw checked background (tile by tile)
  int u_start = u;
  for (y=y_start-tile_h; y<image->height()+tile_h; y+=tile_h) {
    for (x=x_start-tile_w; x<image->width()+tile_w; x+=tile_w) {
      fill_rect(image, x, y, x+tile_w-1, y+tile_h-1,
                (((u+v))&1)? c1: c2);
      ++u;
    }
    u = u_start;
    ++v;
  }
}
コード例 #6
0
ファイル: render.cpp プロジェクト: vmrob/aseprite
static void merge_zoomed_image_scale_down(Image* dst, const Image* src, const Palette* pal,
  int x, int y, int opacity, int blend_mode, Zoom zoom)
{
  BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blend_mode);
  int src_x, src_y, src_w, src_h;
  int dst_x, dst_y, dst_w, dst_h;
  int unbox_w, unbox_h;
  int bottom;

  unbox_w = zoom.remove(1);
  unbox_h = zoom.remove(1);

  src_x = 0;
  src_y = 0;
  src_w = src->width();
  src_h = src->height();

  dst_x = x;
  dst_y = y;
  dst_w = zoom.apply(src->width());
  dst_h = zoom.apply(src->height());

  // clipping...
  if (dst_x < 0) {
    src_x += zoom.remove(-dst_x);
    src_w -= zoom.remove(-dst_x);
    dst_w -= (-dst_x);
    dst_x = 0;
  }

  if (dst_y < 0) {
    src_y += zoom.remove(-dst_y);
    src_h -= zoom.remove(-dst_y);
    dst_h -= (-dst_y);
    dst_y = 0;
  }

  if (dst_x+dst_w > dst->width()) {
    src_w -= zoom.remove(dst_x+dst_w-dst->width());
    dst_w = dst->width() - dst_x;
  }

  if (dst_y+dst_h > dst->height()) {
    src_h -= zoom.remove(dst_y+dst_h-dst->height());
    dst_h = dst->height() - dst_y;
  }

  src_w = zoom.remove(zoom.apply(src_w));
  src_h = zoom.remove(zoom.apply(src_h));

  if ((src_w <= 0) || (src_h <= 0) ||
      (dst_w <= 0) || (dst_h <= 0))
    return;

  bottom = dst_y+dst_h-1;

  // Lock all necessary bits
  const LockImageBits<SrcTraits> srcBits(src, gfx::Rect(src_x, src_y, src_w, src_h));
  LockImageBits<DstTraits> dstBits(dst, gfx::Rect(dst_x, dst_y, dst_w, dst_h));
  typename LockImageBits<SrcTraits>::const_iterator src_it = srcBits.begin();
  typename LockImageBits<SrcTraits>::const_iterator src_end = srcBits.end();
  typename LockImageBits<DstTraits>::iterator dst_it, dst_end;

  // For each line to draw of the source image...
  for (y=0; y<src_h; y+=unbox_h) {
    dst_it = dstBits.begin_area(gfx::Rect(dst_x, dst_y, dst_w, 1));
    dst_end = dstBits.end_area(gfx::Rect(dst_x, dst_y, dst_w, 1));

    for (x=0; x<src_w; x+=unbox_w) {
      ASSERT(src_it >= srcBits.begin() && src_it < src_end);
      ASSERT(dst_it >= dstBits.begin() && dst_it < dst_end);

      blender(*dst_it, *dst_it, *src_it, opacity);

      // Skip source pixels
      for (int delta=0; delta < unbox_w && src_it != src_end; ++delta)
        ++src_it;

      ++dst_it;
    }

    if (++dst_y > bottom)
      break;

    // Skip lines
    for (int delta=0; delta < src_w * (unbox_h-1) && src_it != src_end; ++delta)
      ++src_it;
  }
}
コード例 #7
0
ファイル: render.cpp プロジェクト: vmrob/aseprite
static void merge_zoomed_image_scale_up(Image* dst, const Image* src, const Palette* pal,
  int x, int y, int opacity, int blend_mode, Zoom zoom)
{
  BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blend_mode);
  int src_x, src_y, src_w, src_h;
  int dst_x, dst_y, dst_w, dst_h;
  int box_x, box_y, box_w, box_h;
  int first_box_w, first_box_h;
  int line_h, bottom;

  box_w = zoom.apply(1);
  box_h = zoom.apply(1);

  src_x = 0;
  src_y = 0;
  src_w = src->width();
  src_h = src->height();

  dst_x = x;
  dst_y = y;
  dst_w = zoom.apply(src->width());
  dst_h = zoom.apply(src->height());

  // clipping...
  if (dst_x < 0) {
    src_x += zoom.remove(-dst_x);
    src_w -= zoom.remove(-dst_x);
    dst_w -= (-dst_x);
    first_box_w = box_w - ((-dst_x) % box_w);
    dst_x = 0;
  }
  else
    first_box_w = 0;

  if (dst_y < 0) {
    src_y += zoom.remove(-dst_y);
    src_h -= zoom.remove(-dst_y);
    dst_h -= (-dst_y);
    first_box_h = box_h - ((-dst_y) % box_h);
    dst_y = 0;
  }
  else
    first_box_h = 0;

  if (dst_x+dst_w > dst->width()) {
    src_w -= zoom.remove(dst_x+dst_w-dst->width());
    dst_w = dst->width() - dst_x;
  }

  if (dst_y+dst_h > dst->height()) {
    src_h -= zoom.remove(dst_y+dst_h-dst->height());
    dst_h = dst->height() - dst_y;
  }

  if ((src_w <= 0) || (src_h <= 0) ||
      (dst_w <= 0) || (dst_h <= 0))
    return;

  bottom = dst_y+dst_h-1;

  // the scanline variable is used to blend src/dst pixels one time for each pixel
  typedef std::vector<typename DstTraits::pixel_t> Scanline;
  Scanline scanline(src_w);
  typename Scanline::iterator scanline_it;
#ifdef _DEBUG
  typename Scanline::iterator scanline_end = scanline.end();
#endif

  // Lock all necessary bits
  const LockImageBits<SrcTraits> srcBits(src, gfx::Rect(src_x, src_y, src_w, src_h));
  LockImageBits<DstTraits> dstBits(dst, gfx::Rect(dst_x, dst_y, dst_w, dst_h));
  typename LockImageBits<SrcTraits>::const_iterator src_it = srcBits.begin();
#ifdef _DEBUG
  typename LockImageBits<SrcTraits>::const_iterator src_end = srcBits.end();
#endif
  typename LockImageBits<DstTraits>::iterator dst_it, dst_end;

  // For each line to draw of the source image...
  for (y=0; y<src_h; ++y) {
    dst_it = dstBits.begin_area(gfx::Rect(dst_x, dst_y, dst_w, 1));
    dst_end = dstBits.end_area(gfx::Rect(dst_x, dst_y, dst_w, 1));

    // Read 'src' and 'dst' and blend them, put the result in `scanline'
    scanline_it = scanline.begin();
    for (x=0; x<src_w; ++x) {
      ASSERT(src_it >= srcBits.begin() && src_it < src_end);
      ASSERT(dst_it >= dstBits.begin() && dst_it < dst_end);
      ASSERT(scanline_it >= scanline.begin() && scanline_it < scanline_end);

      blender(*scanline_it, *dst_it, *src_it, opacity);

      ++src_it;

      int delta;
      if ((x == 0) && (first_box_w > 0))
        delta = first_box_w;
      else
        delta = box_w;

      while (dst_it != dst_end && delta-- > 0)
        ++dst_it;

      ++scanline_it;
    }

    // Get the 'height' of the line to be painted in 'dst'
    if ((y == 0) && (first_box_h > 0))
      line_h = first_box_h;
    else
      line_h = box_h;

    // Draw the line in 'dst'
    for (box_y=0; box_y<line_h; ++box_y) {
      dst_it = dstBits.begin_area(gfx::Rect(dst_x, dst_y, dst_w, 1));
      dst_end = dstBits.end_area(gfx::Rect(dst_x, dst_y, dst_w, 1));
      scanline_it = scanline.begin();

      x = 0;

      // first pixel
      if (first_box_w > 0) {
        for (box_x=0; box_x<first_box_w; ++box_x) {
          ASSERT(scanline_it != scanline_end);
          ASSERT(dst_it != dst_end);

          *dst_it = *scanline_it;

          ++dst_it;
          if (dst_it == dst_end)
            goto done_with_line;
        }

        ++scanline_it;
        ++x;
      }

      // the rest of the line
      for (; x<src_w; ++x) {
        for (box_x=0; box_x<box_w; ++box_x) {
          ASSERT(dst_it !=  dst_end);

          *dst_it = *scanline_it;

          ++dst_it;
          if (dst_it == dst_end)
            goto done_with_line;
        }

        ++scanline_it;
      }

done_with_line:;
      if (++dst_y > bottom)
        goto done_with_blit;
    }

    // go to the next line in the source image
    ++src_y;
  }

done_with_blit:;
}
コード例 #8
0
void CompoundUpdateOutputVisitor::_updateZoom(const Compound* compound,
                                              Frame* frame)
{
    Zoom zoom = frame->getNativeZoom();
    Zoom zoom_1;

    if (!zoom.isValid()) // if zoom is not set, auto-calculate from parent
    {
        zoom_1 = compound->getInheritZoom();
        LBASSERT(zoom_1.isValid());
        zoom.x() = 1.0f / zoom_1.x();
        zoom.y() = 1.0f / zoom_1.y();
    }
    else
    {
        zoom_1.x() = 1.0f / zoom.x();
        zoom_1.y() = 1.0f / zoom.y();
    }

    if (frame->getType() == Frame::TYPE_TEXTURE)
    {
        FrameData* frameData = frame->getMasterData();
        frameData->setZoom(zoom_1); // textures are zoomed by input frame
        frame->setZoom(Zoom::NONE);
    }
    else
    {
        Zoom inputZoom;
        /* Output frames downscale pixel data during readback, and upscale it on
         * the input frame by setting the input frame's inherit zoom. */
        if (zoom.x() > 1.0f)
        {
            inputZoom.x() = zoom_1.x();
            zoom.x() = 1.f;
        }
        if (zoom.y() > 1.0f)
        {
            inputZoom.y() = zoom_1.y();
            zoom.y() = 1.f;
        }

        FrameData* frameData = frame->getMasterData();
        frameData->setZoom(inputZoom);
        frame->setZoom(zoom);
    }
}
コード例 #9
0
ファイル: Engine.cpp プロジェクト: aib/glito
void
Engine::zoom() {
    const int imagesWidth  = ( state == SAVEMNG ) ? animationSavedWidth : w();
    const int imagesHeight = ( state == SAVEMNG ) ? animationSavedHeight : h();
    Skeleton skelSubframe;
    // we must check that we are not going to zoom inside the zoom function:
    if ( skel.selected() == 0 ) {
        // this section should be synchronized since the selected function
        // can be changed before its use by Skeleton::subframe
	skel.shiftSelectedFunction(1);
    }
    skelSubframe.subframe(skel);
    Function functionWork;
    const Zoom zoom( skel.findFrame( pointsForFraming, _x, _y, _color ),
		     imagesWidth, imagesHeight, skel.getZoomFunction(), framesPerCycle );
    for ( std::vector< Image* >::const_iterator i = images.begin(); i != images.end(); ++i ) {
	delete *i;
    }
    images.clear();
    for ( int i = 0; i < framesPerCycle; ++i ) {
	images.push_back( buildImage( imagesWidth, imagesHeight, w(), h() ) );
    }
    int idemo = 1;
    const int idemoMax = 3;
    unsigned long clock0 = clock();
    const float dilat0 = 1.0/skelSubframe.getFunction().surface();
    const float dilat1 = 1.0/skel.getFunction().surface();
    const float otherDilat = 1.0/(skel.sumSurfaces() - skel.getFunction().surface());
    while ( idemo <= idemoMax ) {
	for ( int k = 0; k < framesPerCycle; ++k ) {
	    const float rate = (float)k / framesPerCycle;
	    functionWork.spiralMix( skel.getFunction(), skelSubframe.getFunction(), rate );
	    functionWork.calculateTemp();
	    int pointsToCalculate = pointsPerFrame;
	    if ( state == SAVEMNG) {	
		// points(t) = points(0)*(1 + S/s(t) * (1/s(t) - 1/s(0))/(1/s(1) - 1/s(0)) ) 
		pointsToCalculate = (int)( ( 1.0 + (1/functionWork.surface()-dilat0)
					     / (dilat1-dilat0) * dilat1 / otherDilat
					       ) * pointsPerFrame );
		// to avoid explosion of computation time:
		if ( pointsToCalculate > 100 * pointsPerFrame ) {
		    pointsToCalculate = 100 * pointsPerFrame;
		}
	    }
	    for ( int i = 1; clockNumber || i < pointsToCalculate; ++i ) {
		skel.nextPoint( _x, _y, _color );
		float zx = _x;
		float zy = _y;
		functionWork.previousPoint( zx, zy, false );
		zoom.toScreen( zx, zy );
		images[k]->mem_plot( zoom.screenX, zoom.screenY );
		images[k]->mem_coul( zoom.screenX, zoom.screenY, _color );
		if ( clockNumber ) {
		    if ( i % minimalBuiltPoints == 0 ) {
			const unsigned long newClock = clock();
			if ( newClock - clock0 >= intervalFrame * timecv ) {
			    clock0 = newClock;
			    break;
			}
		    }
		}
	    }
	    make_current();
	    images[k]->mem_draw();
	    if ( Fl::ready() ) {
		Fl::check();
	    }
	    if ( state != ANIMATION && state != DEMO && state != SAVEMNG ) {
	        return;
	    }
	}
	if ( state == DEMO ) {
	    ++idemo;
	}
	if ( state == SAVEMNG ) {
	    return;
	}
    }
}