added SPAN_W
[mesa.git] / src / mesa / swrast / s_zoom.c
index a9c5eb8227543d102d29da73dd35a326f2ab23e9..b67a2970109ea0656ec4ffa9322c5334b936164e 100644 (file)
@@ -1,4 +1,3 @@
-/* $Id: s_zoom.c,v 1.20 2003/02/17 15:41:05 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -36,7 +35,7 @@
 
 
 /*
- * Helper function called from _mesa_write_zoomed_rgba/rgb/index_span().
+ * Helper function called from _swrast_write_zoomed_rgba/rgb/index_span().
  */
 static void
 zoom_span( GLcontext *ctx, const struct sw_span *span,
@@ -46,44 +45,58 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
    GLint c0, c1, skipCol;
    GLint i, j;
    const GLuint maxWidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
-   GLchan rgbaSave[MAX_WIDTH][4];
-   GLuint indexSave[MAX_WIDTH];
-   const GLchan (*rgba)[4] = (const GLchan (*)[4]) src;
-   const GLchan (*rgb)[3] = (const GLchan (*)[3]) src;
-   const GLuint *indexes = (const GLuint *) src;
    struct sw_span zoomed;
    struct span_arrays zoomed_arrays;  /* this is big! */
 
-   /* no pixel arrays! */
+   /* no pixel arrays! must be horizontal spans. */
    ASSERT((span->arrayMask & SPAN_XY) == 0);
    ASSERT(span->primitive == GL_BITMAP);
 
    INIT_SPAN(zoomed, GL_BITMAP, 0, 0, 0);
    zoomed.array = &zoomed_arrays;
 
-   zoomed.z = span->z;
-   zoomed.zStep = span->zStep;  /* span->zStep == 0 */
+   /* copy fog interp info */
    zoomed.fog = span->fog;
    zoomed.fogStep = span->fogStep;
+   /* XXX copy texcoord info? */
+
    if (format == GL_RGBA || format == GL_RGB) {
+      /* copy Z info */
+      zoomed.z = span->z;
+      zoomed.zStep = span->zStep;
+      /* we'll generate an array of colorss */
       zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
       zoomed.arrayMask |= SPAN_RGBA;
    }
    else if (format == GL_COLOR_INDEX) {
+      /* copy Z info */
+      zoomed.z = span->z;
+      zoomed.zStep = span->zStep;
+      /* we'll generate an array of color indexes */
       zoomed.interpMask = span->interpMask & ~SPAN_INDEX;
       zoomed.arrayMask |= SPAN_INDEX;
    }
+   else {
+      assert(format == GL_DEPTH_COMPONENT);
+      /* Copy color info */
+      zoomed.red = span->red;
+      zoomed.green = span->green;
+      zoomed.blue = span->blue;
+      zoomed.alpha = span->alpha;
+      zoomed.redStep = span->redStep;
+      zoomed.greenStep = span->greenStep;
+      zoomed.blueStep = span->blueStep;
+      zoomed.alphaStep = span->alphaStep;
+      /* we'll generate an array of depth values */
+      zoomed.interpMask = span->interpMask & ~SPAN_Z;
+      zoomed.arrayMask |= SPAN_Z;
+   }
 
    /*
     * Compute which columns to draw: [c0, c1)
     */
-#if 0
-   c0 = (GLint) span->x;
-   c1 = (GLint) (span->x + span->end * ctx->Pixel.ZoomX);
-#else
-   c0 = (GLint) span->x + skipPixels * ctx->Pixel.ZoomX;
+   c0 = (GLint) (span->x + skipPixels * ctx->Pixel.ZoomX);
    c1 = (GLint) (span->x + (skipPixels + span->end) * ctx->Pixel.ZoomX);
-#endif
    if (c0 == c1) {
       return;
    }
@@ -141,6 +154,7 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
 
    /* zoom the span horizontally */
    if (format == GL_RGBA) {
+      const GLchan (*rgba)[4] = (const GLchan (*)[4]) src;
       if (ctx->Pixel.ZoomX == -1.0F) {
          /* common case */
          for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
@@ -158,12 +172,13 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
                i = span->end + i - 1;
             }
             ASSERT(i >= 0);
-            ASSERT(i < span->end);
+            ASSERT(i < (GLint)  span->end);
             COPY_CHAN4(zoomed.array->rgba[j], rgba[i]);
          }
       }
    }
    else if (format == GL_RGB) {
+      const GLchan (*rgb)[3] = (const GLchan (*)[3]) src;
       if (ctx->Pixel.ZoomX == -1.0F) {
          /* common case */
          for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
@@ -184,7 +199,7 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
                i = span->end + i - 1;
             }
             ASSERT(i >= 0);
-            ASSERT(i < span->end);
+            ASSERT(i < (GLint) span->end);
             zoomed.array->rgba[j][0] = rgb[i][0];
             zoomed.array->rgba[j][1] = rgb[i][1];
             zoomed.array->rgba[j][2] = rgb[i][2];
@@ -193,6 +208,7 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
       }
    }
    else if (format == GL_COLOR_INDEX) {
+      const GLuint *indexes = (const GLuint *) src;
       if (ctx->Pixel.ZoomX == -1.0F) {
          /* common case */
          for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
@@ -210,22 +226,57 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
                i = span->end + i - 1;
             }
             ASSERT(i >= 0);
-            ASSERT(i < span->end);
+            ASSERT(i < (GLint) span->end);
             zoomed.array->index[j] = indexes[i];
          }
       }
    }
+   else {
+      const GLdepth *zValues = (const GLuint *) src;
+      assert(format == GL_DEPTH_COMPONENT);
+      if (ctx->Pixel.ZoomX == -1.0F) {
+         /* common case */
+         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
+            i = span->end - (j + skipCol) - 1;
+            zoomed.array->z[j] = zValues[i];
+         }
+      }
+      else {
+         /* general solution */
+         const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
+         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
+            i = (GLint) ((j + skipCol) * xscale);
+            if (ctx->Pixel.ZoomX < 0.0) {
+               ASSERT(i <= 0);
+               i = span->end + i - 1;
+            }
+            ASSERT(i >= 0);
+            ASSERT(i < (GLint) span->end);
+            zoomed.array->z[j] = zValues[i];
+         }
+      }
+      /* Now, fall into either the RGB or COLOR_INDEX path below */
+      if (ctx->Visual.rgbMode)
+         format = GL_RGBA;
+      else
+         format = GL_COLOR_INDEX;
+   }
+
 
    /* write the span in rows [r0, r1) */
    if (format == GL_RGBA || format == GL_RGB) {
       /* Writing the span may modify the colors, so make a backup now if we're
-       * going to call _mesa_write_zoomed_span() more than once.
+       * going to call _swrast_write_zoomed_span() more than once.
+       * Also, clipping may change the span end value, so store it as well.
        */
+      GLchan rgbaSave[MAX_WIDTH][4];
+      const GLint end = zoomed.end; /* save */
       if (r1 - r0 > 1) {
          MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * 4 * sizeof(GLchan));
       }
       for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
-         _mesa_write_rgba_span(ctx, &zoomed);
+         _swrast_write_rgba_span(ctx, &zoomed);
+         zoomed.end = end;  /* restore */
          if (r1 - r0 > 1) {
             /* restore the colors */
             MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end*4 * sizeof(GLchan));
@@ -233,11 +284,14 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
       }
    }
    else if (format == GL_COLOR_INDEX) {
+      GLuint indexSave[MAX_WIDTH];
+      const GLint end = zoomed.end; /* save */
       if (r1 - r0 > 1) {
          MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
       }
       for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
-         _mesa_write_index_span(ctx, &zoomed);
+         _swrast_write_index_span(ctx, &zoomed);
+         zoomed.end = end;  /* restore */
          if (r1 - r0 > 1) {
             /* restore the colors */
             MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint));
@@ -248,7 +302,7 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
 
 
 void
-_mesa_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
+_swrast_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
                               CONST GLchan rgba[][4], GLint y0,
                               GLint skipPixels )
 {
@@ -257,7 +311,7 @@ _mesa_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
 
 
 void
-_mesa_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
+_swrast_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
                              CONST GLchan rgb[][3], GLint y0,
                              GLint skipPixels )
 {
@@ -266,11 +320,20 @@ _mesa_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
 
 
 void
-_mesa_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
+_swrast_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
                                GLint y0, GLint skipPixels )
 {
-  zoom_span(ctx, span, (const GLvoid *) span->array->index, y0,
-            GL_COLOR_INDEX, skipPixels);
+   zoom_span(ctx, span, (const GLvoid *) span->array->index, y0,
+             GL_COLOR_INDEX, skipPixels);
+}
+
+
+void
+_swrast_write_zoomed_depth_span( GLcontext *ctx, const struct sw_span *span,
+                                 GLint y0, GLint skipPixels )
+{
+   zoom_span(ctx, span, (const GLvoid *) span->array->z, y0,
+             GL_DEPTH_COMPONENT, skipPixels);
 }
 
 
@@ -278,7 +341,7 @@ _mesa_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
  * As above, but write stencil values.
  */
 void
-_mesa_write_zoomed_stencil_span( GLcontext *ctx,
+_swrast_write_zoomed_stencil_span( GLcontext *ctx,
                                  GLuint n, GLint x, GLint y,
                                  const GLstencil stencil[], GLint y0,
                                  GLint skipPixels )
@@ -292,7 +355,7 @@ _mesa_write_zoomed_stencil_span( GLcontext *ctx,
    (void) skipPixels;  /* XXX this shouldn't be ignored */
 
    /* compute width of output row */
-   m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
+   m = (GLint) FABSF( n * ctx->Pixel.ZoomX );
    if (m==0) {
       return;
    }
@@ -360,6 +423,6 @@ _mesa_write_zoomed_stencil_span( GLcontext *ctx,
 
    /* write the span */
    for (r=r0; r<r1; r++) {
-      _mesa_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
+      _swrast_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
    }
 }