int wrap (Sampler::WrapMode mode, int c, int size)
{
	switch (mode)
	{
		// \note CL and GL modes are handled identically here, as verification process accounts for
		//		 accuracy differences caused by different methods (wrapping vs. denormalizing first).
		case tcu::Sampler::CLAMP_TO_BORDER:
			return deClamp32(c, -1, size);

		case tcu::Sampler::CLAMP_TO_EDGE:
			return deClamp32(c, 0, size-1);

		case tcu::Sampler::REPEAT_GL:
		case tcu::Sampler::REPEAT_CL:
			return imod(c, size);

		case tcu::Sampler::MIRRORED_REPEAT_GL:
		case tcu::Sampler::MIRRORED_REPEAT_CL:
			return (size - 1) - mirror(imod(c, 2*size) - size);

		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}
Exemple #2
0
/* Initialize the filling state. */
static int
tile_fill_init(tile_fill_state_t * ptfs, const gx_device_color * pdevc,
               gx_device * dev, bool set_mask_phase)
{
    gx_color_tile *m_tile = pdevc->mask.m_tile;
    int px, py;

    ptfs->pdevc = pdevc;
    if (m_tile == 0) {          /* no clipping */
        ptfs->pcdev = dev;
        ptfs->phase = pdevc->phase;
        return 0;
    }
    ptfs->pcdev = (gx_device *) & ptfs->cdev;
    ptfs->tmask = &m_tile->tmask;
    ptfs->phase.x = pdevc->mask.m_phase.x;
    ptfs->phase.y = pdevc->mask.m_phase.y;
    /*
     * For non-simple tiles, the phase will be reset on each pass of the
     * tile_by_steps loop, but for simple tiles, we must set it now.
     */
    if (set_mask_phase && m_tile->is_simple) {
        px = imod(-(int)fastfloor(m_tile->step_matrix.tx - ptfs->phase.x + 0.5),
                  m_tile->tmask.rep_width);
        py = imod(-(int)fastfloor(m_tile->step_matrix.ty - ptfs->phase.y + 0.5),
                  m_tile->tmask.rep_height);
    } else
        px = py = 0;
    return tile_clip_initialize(&ptfs->cdev, ptfs->tmask, dev, px, py, NULL);
}
Exemple #3
0
int
gx_trans_pattern_fill_rect(int xmin, int ymin, int xmax, int ymax, gx_color_tile *ptile,
                               gx_pattern_trans_t *fill_trans_buffer, 
                               gs_int_point phase)
{

    tile_fill_trans_state_t state;
    int code;

    if (ptile == 0)             /* null pattern */
        return 0;

    /* Fit fill */
    if ( (xmin | ymin) < 0 ) {
        if ( xmin < 0 )
	    xmin = 0;
        if ( ymin < 0 )
            ymin = 0;
    }

    state.phase.x = phase.x;
    state.phase.y = phase.y;

    if (ptile->is_simple && ptile->cdev == NULL) {
        /* A simple case.  Tile is not clist and simple. */
        int px =
            imod(-(int)fastfloor(ptile->step_matrix.tx - phase.x + 0.5),
                  ptile->ttrans->width);
        int py =
            imod(-(int)fastfloor(ptile->step_matrix.ty - phase.y + 0.5),
                 ptile->ttrans->height);
        
        tile_rect_trans_simple(xmin, ymin, xmax, ymax, px, py, ptile,
            fill_trans_buffer);
    } else {
        if (ptile->cdev == NULL) {
            /* No clist for the pattern, but a complex case
               This portion transforms the bounding box by the step matrix
               and does partial rect fills with tiles that fall into this
               transformed bbox */
            code = tile_by_steps_trans(&state, xmin, ymin, xmax-xmin, ymax-ymin,
                fill_trans_buffer, ptile);
        } else {
            /* clist for the tile.  Currently this is not implemented
               for the case when the tile has transparency.  This is
               on the to do list.  Right now, all tiles with transparency
               are rendered into the pattern cache or into the clist
               */
            return_error(gs_error_unregistered);
        }
    }
return(0);
}
Exemple #4
0
/* Note that we treat this as "texture" for RasterOp. */
static int
tile_colored_fill(const tile_fill_state_t * ptfs,
                  int x, int y, int w, int h)
{
    gx_color_tile *ptile = ptfs->pdevc->colors.pattern.p_tile;
    gs_logical_operation_t lop = ptfs->lop;
    const gx_rop_source_t *source = ptfs->source;
    const gx_rop_source_t *rop_source = ptfs->rop_source;
    gx_device *dev = ptfs->orig_dev;
    int xoff = ptfs->xoff, yoff = ptfs->yoff;
    gx_strip_bitmap *bits = &ptile->tbits;
    const byte *data = bits->data;
    bool full_transfer = (w == ptfs->w0 && h == ptfs->h0);
    gx_bitmap_id source_id =
    (full_transfer ? rop_source->id : gx_no_bitmap_id);
    int code;

    if (source == NULL && lop_no_S_is_T(lop))
        code = (*dev_proc(ptfs->pcdev, copy_color))
            (ptfs->pcdev, data + bits->raster * yoff, xoff,
             bits->raster,
             (full_transfer ? bits->id : gx_no_bitmap_id),
             x, y, w, h);
    else {
        gx_strip_bitmap data_tile;

        data_tile.data = (byte *) data;         /* actually const */
        data_tile.raster = bits->raster;
        data_tile.size.x = data_tile.rep_width = ptile->tbits.size.x;
        data_tile.size.y = data_tile.rep_height = ptile->tbits.size.y;
        data_tile.id = bits->id;
        data_tile.shift = data_tile.rep_shift = 0;
        code = (*dev_proc(dev, strip_copy_rop))
            (dev,
             rop_source->sdata + (y - ptfs->y0) * rop_source->sraster,
             rop_source->sourcex + (x - ptfs->x0),
             rop_source->sraster, source_id,
             (rop_source->use_scolors ? rop_source->scolors : NULL),
             &data_tile, NULL,
             x, y, w, h,
             imod(xoff - x, data_tile.rep_width),
             imod(yoff - y, data_tile.rep_height),
             lop);
    }
    return code;
}
Exemple #5
0
vector* vec_mod_vec_int(vector *a, entry b) {
    vector* result;
    _index i;
    if (b<0)
	error("LiE can only take the modulus by a positive number.\n");
    result = mkvector(a->ncomp);
    for (i = 0; i<a->ncomp; i++)
	result->compon[i] = imod(a->compon[i],b);
    return result;
}
Exemple #6
0
void fillGaussianKernel(FFT_t *transformer, double s)
{
  //-- A kernel should be placed in this way
  //--  1.0  0.6   0   0   0  0.6
  //--  0.6  0.1   0   0   0  0.1
  //--    0    0   0   0   0    0
  //--    0    0   0   0   0    0
  //--    0    0   0   0   0    0
  //--  0.6  0.1   0   0   0  0.1
  //-- 
  //-- Gaussian kernel:
  //-- exp[-(x^2 + y^2)/s^2]
  //-- where s is theta_G / theta_pix
  
  double *kernel = transformer->kernel;
  double s_sq    = SQ(s);                    //-- [pix^2]
  double cut     = CUTOFF_FACTOR_FILTER * s; //-- CUTOFF_FACTOR_FILTER set to 2.2 in peakParameters.h, equivalent to a Gaussian trunked at 3 sigma
  double cut_sq  = SQ(cut);                  //-- [pix^2]
  
  int M1    = transformer->N1; //-- M1, M2 are resolution + size of zero padding
  int M2    = transformer->N2;
  int upper = (int)ceil(cut);
  
  double value, sum = 0.0;
  int i, j, r_sq;
  for (i=-upper; i<=upper; i++) {
    for (j=-upper; j<=upper; j++) {
      r_sq = SUM_SQ_2(i, j);
      if (r_sq > cut_sq) continue;
      value = exp(-r_sq / s_sq);
      sum += value;
      kernel[imod(M1, i) + imod(M2, j) * M1] = value;
    }
  }
  
  //-- Normalization
  for (i=0; i<transformer->length; i++) kernel[i] /= sum;
  
  //-- To Fourier space
  fftw_execute(transformer->kernel_p);
  return;
}
Exemple #7
0
matrix *mat_mod_mat_int(matrix *a, entry b) {
    _index  i, j;
    _index m = a->nrows, n = a->ncols;
    matrix* result;
    if (b<0)
	error("LiE can only take the modulus by a positive number.\n");
    result = mkmatrix(a->nrows, a->ncols);
    for (i = 0; i<m; i++)
    for (j = 0; j<n; j++)
	*(*(result->elm + i) + j) =
	imod(*(*(a->elm + i)+j), b);
    return result;
}
Exemple #8
0
/* Compute the derived values of a halftone tile. */
void
gx_compute_cell_values(gx_ht_cell_params_t * phcp)
{
    const int M = phcp->M, N = phcp->N, M1 = phcp->M1, N1 = phcp->N1;
    const uint m = any_abs(M), n = any_abs(N);
    const uint m1 = any_abs(M1), n1 = any_abs(N1);
    const ulong C = phcp->C = (ulong)m * m1 + (ulong)n * n1;
    const int D = phcp->D = igcd(m1, n);
    const int D1 = phcp->D1 = igcd(m, n1);

    phcp->W = C / D, phcp->W1 = C / D1;
    /* Compute the shift value. */
    /* If M1 or N is zero, the shift is zero. */
    if (M1 && N) {
        int h = 0, k = 0, dy = 0;
        int shift;

        /*
         * There may be a faster way to do this: see Knuth vol. 2,
         * section 4.5.2, Algorithm X (p. 302) and exercise 15
         * (p. 315, solution p. 523).
         */
        while (dy != D)
            if (dy > D) {
                if (M1 > 0)
                    ++k;
                else
                    --k;
                dy -= m1;
            } else {
                if (N > 0)
                    ++h;
                else
                    --h;
                dy += n;
            }
        shift = h * M + k * N1;
        /* We just computed what amounts to a right shift; */
        /* what we want is a left shift. */
        phcp->S = imod(-shift, phcp->W);
    } else
        phcp->S = 0;
    if_debug12('h', "[h]MNR=(%d,%d)/%d, M'N'R'=(%d,%d)/%d => C=%lu, D=%d, D'=%d, W=%u, W'=%u, S=%d\n",
               M, N, phcp->R, M1, N1, phcp->R1,
               C, D, D1, phcp->W, phcp->W1, phcp->S);
}
Exemple #9
0
gint zeroRem(gint upDown, gint y, gint x, gint *quo, gint *newY) {
	if (x==0) 
		return (localError("zeroRem: received zero denominator"),-1);
	if (upDown!=-1 && upDown!=1) 
		return (localError("zeroRem: upDown must be +/-1"),-1);
	if (y==0) {
		*quo=0;
		*newY=y;
		return 0;
	} else {
		gint rem;
		imod(y,x,quo,&rem);
		if (rem==0) {
			*newY=y; /*leave quo as is*/
			return 0;
		} else {
			*newY=y+upDown*x-rem;
			(*quo)+=upDown;
			return 0;
		}
	}
}
Exemple #10
0
int
gx_trans_pattern_fill_rect(int xmin, int ymin, int xmax, int ymax,
                           gx_color_tile *ptile,
                           gx_pattern_trans_t *fill_trans_buffer,
                           gs_int_point phase, gx_device *dev,
                           const gx_device_color * pdevc)
{

    tile_fill_trans_state_t state_trans;
    tile_fill_state_t state_clist_trans;
    int code;

    if (ptile == 0)             /* null pattern */
        return 0;

    /* Fit fill */
    if ( (xmin | ymin) < 0 ) {
        if ( xmin < 0 )
            xmin = 0;
        if ( ymin < 0 )
            ymin = 0;
    }

    /* Initialize the fill state */
    state_trans.phase.x = phase.x;
    state_trans.phase.y = phase.y;

    if (ptile->is_simple && ptile->cdev == NULL) {
        /* A simple case.  Tile is not clist and simple. */
        int px =
            imod(-(int)fastfloor(ptile->step_matrix.tx - phase.x + 0.5),
                  ptile->ttrans->width);
        int py =
            imod(-(int)fastfloor(ptile->step_matrix.ty - phase.y + 0.5),
                 ptile->ttrans->height);

        tile_rect_trans_simple(xmin, ymin, xmax, ymax, px, py, ptile,
            fill_trans_buffer);
    } else {
        if (ptile->cdev == NULL) {
            /* No clist for the pattern, but a complex case
               This portion transforms the bounding box by the step matrix
               and does partial rect fills with tiles that fall into this
               transformed bbox */
            code = tile_by_steps_trans(&state_trans, xmin, ymin, xmax-xmin,
                                        ymax-ymin, fill_trans_buffer, ptile);
        } else {
            /* clist for the trans tile.  This uses the pdf14 device as a target
               and should blend directly into the buffer.  Note that the
               pattern can not have a push pdf14 device or a pop pdf14 device
               compositor action.  Those are removed during the compositor
               clist writing operation where we check for the case of a pattern
               with a transparency */
            gx_device_clist *cdev = ptile->cdev;
            gx_device_clist_reader *crdev = (gx_device_clist_reader *)cdev;
            gx_strip_bitmap tbits;

            code = tile_fill_init(&state_clist_trans, pdevc, dev, false);

            state_clist_trans.phase.x = phase.x;
            state_clist_trans.phase.y = phase.y;
            crdev->yplane.depth = 0;
            crdev->yplane.shift = 0;
            crdev->yplane.index = -1;
            crdev->pages = NULL;
            crdev->num_pages = 1;
            state_clist_trans.orig_dev = dev;
            state_clist_trans.pdevc = pdevc;
            tbits = ptile->tbits;
            tbits.size.x = crdev->width;
            tbits.size.y = crdev->height;
            code = tile_by_steps(&state_clist_trans, xmin, ymin, xmax,
                                 ymax, ptile, &tbits, tile_pattern_clist);
        }
    }
    return(0);
}
Exemple #11
0
/*
 * This is somewhat a clone of the tile_by_steps function but one
 * that performs filling from and to pdf14dev (transparency) buffers.
 * At some point it may be desirable to do some optimization here.
 */
static int
tile_by_steps_trans(tile_fill_trans_state_t * ptfs, int x0, int y0, int w0, int h0,
              gx_pattern_trans_t *fill_trans_buffer, const gx_color_tile * ptile)
{
    int x1 = x0 + w0, y1 = y0 + h0;
    int i0, i1, j0, j1, i, j;
    gs_matrix step_matrix;      /* translated by phase */
    gx_pattern_trans_t *ptrans_pat = ptile->ttrans;

    ptfs->x0 = x0, ptfs->w0 = w0;
    ptfs->y0 = y0, ptfs->h0 = h0;
    step_matrix = ptile->step_matrix;
    step_matrix.tx -= ptfs->phase.x;
    step_matrix.ty -= ptfs->phase.y;
    {
        gs_rect bbox;           /* bounding box in device space */
        gs_rect ibbox;          /* bounding box in stepping space */
        double bbw = ptile->bbox.q.x - ptile->bbox.p.x;
        double bbh = ptile->bbox.q.y - ptile->bbox.p.y;
        double u0, v0, u1, v1;

        bbox.p.x = x0, bbox.p.y = y0;
        bbox.q.x = x1, bbox.q.y = y1;
        gs_bbox_transform_inverse(&bbox, &step_matrix, &ibbox);
        if_debug10('T',
          "[T]x,y=(%d,%d) w,h=(%d,%d) => (%g,%g),(%g,%g), offset=(%g,%g)\n",
                   x0, y0, w0, h0,
                   ibbox.p.x, ibbox.p.y, ibbox.q.x, ibbox.q.y,
                   step_matrix.tx, step_matrix.ty);
        /*
         * If the pattern is partly transparent and XStep/YStep is smaller
         * than the device space BBox, we need to ensure that we cover
         * each pixel of the rectangle being filled with *every* pattern
         * that overlaps it, not just *some* pattern copy.
         */
        u0 = ibbox.p.x - max(ptile->bbox.p.x, 0) - 0.000001;
        v0 = ibbox.p.y - max(ptile->bbox.p.y, 0) - 0.000001;
        u1 = ibbox.q.x - min(ptile->bbox.q.x, 0) + 0.000001;
        v1 = ibbox.q.y - min(ptile->bbox.q.y, 0) + 0.000001;
        if (!ptile->is_simple)
            u0 -= bbw, v0 -= bbh, u1 += bbw, v1 += bbh;
        i0 = (int)fastfloor(u0);
        j0 = (int)fastfloor(v0);
        i1 = (int)ceil(u1);
        j1 = (int)ceil(v1);
    }
    if_debug4('T', "[T]i=(%d,%d) j=(%d,%d)\n", i0, i1, j0, j1);
    for (i = i0; i < i1; i++)
        for (j = j0; j < j1; j++) {
            int x = (int)fastfloor(step_matrix.xx * i +
                          step_matrix.yx * j + step_matrix.tx);
            int y = (int)fastfloor(step_matrix.xy * i +
                          step_matrix.yy * j + step_matrix.ty);
            int w = ptrans_pat->width;
            int h = ptrans_pat->height;
            int xoff, yoff;
            int px, py;

            if_debug4('T', "[T]i=%d j=%d x,y=(%d,%d)", i, j, x, y);
            if (x < x0)
                xoff = x0 - x, x = x0, w -= xoff;
            else
                xoff = 0;
            if (y < y0)
                yoff = y0 - y, y = y0, h -= yoff;
            else
                yoff = 0;
            if (x + w > x1)
                w = x1 - x;
            if (y + h > y1)
                h = y1 - y;
            if_debug6('T', "=>(%d,%d) w,h=(%d,%d) x/yoff=(%d,%d)\n",
                      x, y, w, h, xoff, yoff);
            if (w > 0 && h > 0) {

                px = imod(xoff - x, ptile->ttrans->width);
                py = imod(yoff - y, ptile->ttrans->height);

                /* Set the offsets for colored pattern fills */
                ptfs->xoff = xoff;
                ptfs->yoff = yoff;

                /* We only go through blending during tiling, if
                   there was overlap as defined by the step matrix
                   and the bounding box */

                ptile->ttrans->pat_trans_fill(x, y, x+w, y+h, px, py, ptile,
                        fill_trans_buffer);
            }
        }
    return 0;
}
Exemple #12
0
int
gx_dc_pattern_fill_rectangle(const gx_device_color * pdevc, int x, int y,
                             int w, int h, gx_device * dev,
                             gs_logical_operation_t lop,
                             const gx_rop_source_t * source)
{
    gx_color_tile *ptile = pdevc->colors.pattern.p_tile;
    const gx_rop_source_t *rop_source = source;
    gx_rop_source_t no_source;
    gx_strip_bitmap *bits;
    tile_fill_state_t state;
    int code;

    if (ptile == 0)             /* null pattern */
        return 0;
    if (rop_source == NULL)
        set_rop_no_source(rop_source, no_source, dev);
    bits = &ptile->tbits;

    state.cdev.finalize = 0;

    code = tile_fill_init(&state, pdevc, dev, false);
    if (code < 0)
        return code;
    if (ptile->is_simple && ptile->cdev == NULL) {
        int px =
            imod(-(int)fastfloor(ptile->step_matrix.tx - state.phase.x + 0.5),
                 bits->rep_width);
        int py =
            imod(-(int)fastfloor(ptile->step_matrix.ty - state.phase.y + 0.5),
                 bits->rep_height);

        if (state.pcdev != dev)
            tile_clip_set_phase(&state.cdev, px, py);
        /* RJW: Can we get away with calling the simpler version? Not
         * if we are working in planar mode because the default
         * strip_tile_rectangle doesn't understand bits being in planar
         * mode at the moment.
         */
        if (source == NULL && lop_no_S_is_T(lop) && state.num_planes == -1)
            code = (*dev_proc(state.pcdev, strip_tile_rectangle))
                (state.pcdev, bits, x, y, w, h,
                 gx_no_color_index, gx_no_color_index, px, py);
        else if (rop_source->planar_height == 0)
            code = (*dev_proc(state.pcdev, strip_copy_rop))
                        (state.pcdev,
                         rop_source->sdata, rop_source->sourcex,
                         rop_source->sraster, rop_source->id,
                         (rop_source->use_scolors ? rop_source->scolors : NULL),
                         bits, NULL, x, y, w, h, px, py, lop);
        else
            code = (*dev_proc(state.pcdev, strip_copy_rop2))
                        (state.pcdev,
                         rop_source->sdata, rop_source->sourcex,
                         rop_source->sraster, rop_source->id,
                         (rop_source->use_scolors ? rop_source->scolors : NULL),
                         bits, NULL, x, y, w, h, px, py, lop,
                         rop_source->planar_height);
    } else {
        state.lop = lop;
        state.source = source;
        state.orig_dev = dev;
        if (ptile->cdev == NULL) {
            code = tile_by_steps(&state, x, y, w, h, ptile,
                                 &ptile->tbits, tile_colored_fill);
        } else {
            gx_device_clist *cdev = ptile->cdev;
            gx_device_clist_reader *crdev = (gx_device_clist_reader *)cdev;
            gx_strip_bitmap tbits;

            crdev->yplane.depth = 0; /* Don't know what to set here. */
            crdev->yplane.shift = 0;
            crdev->yplane.index = -1;
            crdev->pages = NULL;
            crdev->num_pages = 1;
            state.orig_dev = dev;
            tbits = ptile->tbits;
            tbits.size.x = crdev->width;
            tbits.size.y = crdev->height;
            code = tile_by_steps(&state, x, y, w, h, ptile,
                                 &tbits, tile_pattern_clist);
        }
    }
    if(state.cdev.finalize)
        state.cdev.finalize((gx_device *)&state.cdev);
    return code;
}
Exemple #13
0
/* Note that we treat this as "texture" for RasterOp. */
static int
tile_colored_fill(const tile_fill_state_t * ptfs,
                  int x, int y, int w, int h)
{
    gx_color_tile *ptile = ptfs->pdevc->colors.pattern.p_tile;
    gs_logical_operation_t lop = ptfs->lop;
    const gx_rop_source_t *source = ptfs->source;
    gx_device *dev = ptfs->orig_dev;
    int xoff = ptfs->xoff, yoff = ptfs->yoff;
    gx_strip_bitmap *bits = &ptile->tbits;
    const byte *data = bits->data;
    bool full_transfer = (w == ptfs->w0 && h == ptfs->h0);
    int code = 0;

    if (source == NULL && lop_no_S_is_T(lop) && ptfs->num_planes < 0) {
        /* RJW: Ideally, we'd like to remove the 'ptfs->num_planes < 0' test
         * above, and then do:
         *
         * if (ptfs->num_planes >= 0) {
         *     int plane_step = ptile->tbits.raster * ptile->tbits.rep_height;
         *     int k;
         *     for (k = 0; k < ptfs->num_planes; k++) {
         *         byte *data_plane = (byte*) (data + plane_step * k);
         *         (*dev_proc(ptfs->pcdev, copy_plane))
         *                                 (ptfs->pcdev,
         *                                  data_plane + bits->raster * yoff,
         *                                  xoff, bits->raster,
         *                                  gx_no_bitmap_id, x, y,
         *                                  w, h, k);
         *     }
         * } else
         *
         * Unfortunately, this can cause the rop source device to be called
         * with copy_plane. This is currently broken (and I fear cannot ever
         * be done properly). We therefore drop back to the strip_copy_rop
         * case below.
         */
        {
            code = (*dev_proc(ptfs->pcdev, copy_color))
                    (ptfs->pcdev, data + bits->raster * yoff, xoff,
                     bits->raster,
                     (full_transfer ? bits->id : gx_no_bitmap_id),
                     x, y, w, h);
        }
    } else {
        gx_strip_bitmap data_tile;
        gx_bitmap_id source_id;
        gx_rop_source_t no_source;

        if (source == NULL)
            set_rop_no_source(source, no_source, dev);
        source_id = (full_transfer ? source->id : gx_no_bitmap_id);
        data_tile.data = (byte *) data;         /* actually const */
        data_tile.raster = bits->raster;
        data_tile.size.x = data_tile.rep_width = ptile->tbits.size.x;
        data_tile.size.y = data_tile.rep_height = ptile->tbits.size.y;
        data_tile.id = bits->id;
        data_tile.shift = data_tile.rep_shift = 0;
        data_tile.num_planes = (ptfs->num_planes > 1 ? ptfs->num_planes : 1);
        if (source->planar_height == 0) {
            code = (*dev_proc(ptfs->pcdev, strip_copy_rop))
                           (ptfs->pcdev,
                            source->sdata + (y - ptfs->y0) * source->sraster,
                            source->sourcex + (x - ptfs->x0),
                            source->sraster, source_id,
                            (source->use_scolors ? source->scolors : NULL),
                            &data_tile, NULL,
                            x, y, w, h,
                            imod(xoff - x, data_tile.rep_width),
                            imod(yoff - y, data_tile.rep_height),
                            lop);
        } else {
            code = (*dev_proc(ptfs->pcdev, strip_copy_rop2))
                           (ptfs->pcdev,
                            source->sdata + (y - ptfs->y0) * source->sraster,
                            source->sourcex + (x - ptfs->x0),
                            source->sraster, source_id,
                            (source->use_scolors ? source->scolors : NULL),
                            &data_tile, NULL,
                            x, y, w, h,
                            imod(xoff - x, data_tile.rep_width),
                            imod(yoff - y, data_tile.rep_height),
                            lop,
                            source->planar_height);
        }
    }
    return code;
}
Exemple #14
0
/*
 * Fill with non-standard X and Y stepping.
 * ptile is pdevc->colors.pattern.{m,p}_tile.
 * tbits_or_tmask is whichever of tbits and tmask is supplying
 * the tile size.
 * This implementation could be sped up considerably!
 */
static int
tile_by_steps(tile_fill_state_t * ptfs, int x0, int y0, int w0, int h0,
              const gx_color_tile * ptile,
              const gx_strip_bitmap * tbits_or_tmask,
              int (*fill_proc) (const tile_fill_state_t * ptfs,
                                int x, int y, int w, int h))
{
    int x1 = x0 + w0, y1 = y0 + h0;
    int i0, i1, j0, j1, i, j;
    gs_matrix step_matrix;      /* translated by phase */
    int code;

    ptfs->x0 = x0, ptfs->w0 = w0;
    ptfs->y0 = y0, ptfs->h0 = h0;
    step_matrix = ptile->step_matrix;
    step_matrix.tx -= ptfs->phase.x;
    step_matrix.ty -= ptfs->phase.y;
    {
        gs_rect bbox;           /* bounding box in device space */
        gs_rect ibbox;          /* bounding box in stepping space */
        double bbw = ptile->bbox.q.x - ptile->bbox.p.x;
        double bbh = ptile->bbox.q.y - ptile->bbox.p.y;
        double u0, v0, u1, v1;

        bbox.p.x = x0, bbox.p.y = y0;
        bbox.q.x = x1, bbox.q.y = y1;
        gs_bbox_transform_inverse(&bbox, &step_matrix, &ibbox);
        if_debug10('T',
          "[T]x,y=(%d,%d) w,h=(%d,%d) => (%g,%g),(%g,%g), offset=(%g,%g)\n",
                   x0, y0, w0, h0,
                   ibbox.p.x, ibbox.p.y, ibbox.q.x, ibbox.q.y,
                   step_matrix.tx, step_matrix.ty);
        /*
         * If the pattern is partly transparent and XStep/YStep is smaller
         * than the device space BBox, we need to ensure that we cover
         * each pixel of the rectangle being filled with *every* pattern
         * that overlaps it, not just *some* pattern copy.
         */
        u0 = ibbox.p.x - max(ptile->bbox.p.x, 0) - 0.000001;
        v0 = ibbox.p.y - max(ptile->bbox.p.y, 0) - 0.000001;
        u1 = ibbox.q.x - min(ptile->bbox.q.x, 0) + 0.000001;
        v1 = ibbox.q.y - min(ptile->bbox.q.y, 0) + 0.000001;
        if (!ptile->is_simple)
            u0 -= bbw, v0 -= bbh, u1 += bbw, v1 += bbh;
        i0 = (int)fastfloor(u0);
        j0 = (int)fastfloor(v0);
        i1 = (int)ceil(u1);
        j1 = (int)ceil(v1);
    }
    if_debug4('T', "[T]i=(%d,%d) j=(%d,%d)\n", i0, i1, j0, j1);
    for (i = i0; i < i1; i++)
        for (j = j0; j < j1; j++) {
            int x = (int)fastfloor(step_matrix.xx * i +
                          step_matrix.yx * j + step_matrix.tx);
            int y = (int)fastfloor(step_matrix.xy * i +
                          step_matrix.yy * j + step_matrix.ty);
            int w = tbits_or_tmask->size.x;
            int h = tbits_or_tmask->size.y;
            int xoff, yoff;

            if_debug4('T', "[T]i=%d j=%d x,y=(%d,%d)", i, j, x, y);
            if (x < x0)
                xoff = x0 - x, x = x0, w -= xoff;
            else
                xoff = 0;
            if (y < y0)
                yoff = y0 - y, y = y0, h -= yoff;
            else
                yoff = 0;
            if (x + w > x1)
                w = x1 - x;
            if (y + h > y1)
                h = y1 - y;
            if_debug6('T', "=>(%d,%d) w,h=(%d,%d) x/yoff=(%d,%d)\n",
                      x, y, w, h, xoff, yoff);
            if (w > 0 && h > 0) {
                if (ptfs->pcdev == (gx_device *) & ptfs->cdev)
                    tile_clip_set_phase(&ptfs->cdev,
                                imod(xoff - x, ptfs->tmask->rep_width),
                                imod(yoff - y, ptfs->tmask->rep_height));
                /* Set the offsets for colored pattern fills */
                ptfs->xoff = xoff;
                ptfs->yoff = yoff;
                code = (*fill_proc) (ptfs, x, y, w, h);
                if (code < 0)
                    return code;
            }
        }
    return 0;
}
void Parallelogram::setContact2(const Ball_p& b, Ball_v& ball, Obj_v& obj, uint32_t counter){
	/*
	for(auto c:b->conC){
		if(c->num == num && c->type == ObjType::O) return;
	}
	auto& t = b->touchArea[num];
	if(!t->collidable) return;
	// 円がどの辺・角と衝突するか判定
	checkArea(b, b->p);
	// 円が内部に入っている場合
	if(t->side == 5){
		if(b->shootFrame == counter) checkArea(b, ball[0]->p);
		checkArea(b, b->p-b->v);
		if(t->side == 5) b->toScatter = true;
		return;
	}
	// この場合は角に当たる
	if(t->side%2==1){
		const Arg arg = t->p.arg(b->p);
		// 接点がどのdotの間にあるのか調べる。kがdot_numberになる
		int k;
		for(k = 0; k < dotL; k++){
			if(arg < b->dot[k].arg-b->dot[0].arg) break;
		}
		const int dotN = imod(k);
		const double s = (arg-b->dot[imod(dotN-1)].arg)/(b->dot[dotN].arg-b->dot[imod(dotN-1)].arg);
		const Arg tan1 = b->dot[dotN].abs.arg(b->dot[imod(dotN-2)].abs);
		const Arg tan2 = b->dot[imod(dotN+1)].abs.arg(b->dot[imod(dotN-1)].abs);
		const double exc = -(b->dot[imod(dotN-1)].abs-b->dot[dotN].abs)^(t->p-b->dot[dotN].abs);
		if(exc < 0 && exc > -b->size){
			con.push_back(std::make_shared<Contact>());
			b->conD.push_back(std::make_shared<Contact>());
			b->bezD.push_back(std::make_shared<Bezier>());
			
			auto& c1 = con.back();
			auto& c2 = b->conD.back();
			c1->p = t->p;
			c1->exc = -exc;
			c1->num = b->num;
			c1->type = ObjType::D;
			c1->weight = b->weight;
			c1->arg = arg+PI;
			c1->color = b->color;
			c1->side = t->side;
			c1->pairP = b->p;
			c1->pairV = b->v;
			
			c2->p = t->p;
			c2->dist = c2->p.dist(b->p);
			c2->exc = -exc;
			c2->arg = arg;
			c2->tan = (1.0-s)*tan1+s*tan2;
			c2->num = num;
			c2->type = ObjType::O;
			c2->side = t->side;
		}
	// この場合は辺に当たる
	}else if(t->side%2==0){
		const Arg arg = t->arg+PI;
		int dotN = imod(round(arg.val()*dotL/PI2));
		// 壁に垂直な向きへの長さが一番大きい点を調べる
		if(b->dot[imod(dotN+1)].rel*pol(arg) > b->dot[imod(dotN-1)].rel*pol(arg)){
			while(b->dot[imod(dotN+1)].rel*pol(arg) > b->dot[dotN].rel*pol(arg)){
				dotN = imod(dotN+1);
			}
		}else{
			while(b->dot[imod(dotN-1)].rel*pol(arg) > b->dot[dotN].rel*pol(arg)){
				dotN = imod(dotN-1);
			}
		}
		if((b->dot[dotN].abs-t->p)*pol(arg) >= 0.0){
			con.push_back(std::make_shared<Contact>());
			b->conD.push_back(std::make_shared<Contact>());
			b->bezD.push_back(std::make_shared<Bezier>());
			
			auto& c1 = con.back();
			auto& c2 = b->conD.back();
			if(std::abs(b->dot[dotN].abs.x-b->p.x) < 1.0e-6){
				c1->p = c2->p = t->p;
			}else if(tan(arg) < 1.0e-6){
				c1->p.x = c2->p.x = t->p.x;
				c1->p.y = c2->p.y = b->p.y;
			}else{
				const double a1 = (b->dot[dotN].abs.y-b->p.y)/(b->dot[dotN].abs.x-b->p.x);
				const double a3 = -1.0/tan(arg);
				c1->p.x = (a1*b->p.x-b->p.y-a3*t->p.x+t->p.y)/(a1-a3);
				c1->p.y = a1*(c1->p.x-b->p.x)+b->p.y;
				c2->p.x = (a1*b->p.x-b->p.y-a3*t->p.x+t->p.y)/(a1-a3);
				c2->p.y = a1*(c2->p.x-b->p.x)+b->p.y;
			}
			c1->exc = (b->dot[dotN].abs-c1->p)*pol(PI-arg);
			c1->num = b->num;
			c1->type = ObjType::D;
			c1->weight = b->weight;
			c1->arg = arg;
			c1->color = b->color;
			c1->side = t->side;
			c1->pairP = b->p;
			c1->pairV = b->v;
			
			c2->dist = c2->p.dist(b->p);
			c2->exc = (b->dot[dotN].abs-c2->p)*pol(PI-arg);
			c2->arg = c2->p.arg(b->p);
			c2->tan = arg+PI_2;
			c2->num = num;
			c2->type = ObjType::O;
			c2->side = t->side;
		}
	}else{
		printf("$\n");
	}
	*/
	for(int i = 0; i < b->conS1; i++){
		if(b->con[i]->num == num && b->con[i]->type == ObjType::O) return;
	}
	auto& t = b->touchArea[num];
	if(!t->collidable) return;
	// 円がどの辺・角と衝突するか判定
	checkArea(b, b->p);
	// 円が内部に入っている場合
	if(t->side == 5){
		if(b->shootFrame == counter) checkArea(b, ball[0]->p);
		checkArea(b, b->p-b->v);
		if(t->side == 5) b->toScatter = true;
		return;
	}
	// この場合は角に当たる
	if(t->side%2==1){
		const Arg arg = t->p.arg(b->p);
		// 接点がどのdotの間にあるのか調べる。kがdot_numberになる
		int k;
		for(k = 0; k < dotL; k++){
			if(arg < b->dot[k].arg-b->dot[0].arg) break;
		}
		const int dotN = imod(k);
		const double s = (arg-b->dot[imod(dotN-1)].arg)/(b->dot[dotN].arg-b->dot[imod(dotN-1)].arg);
		const Arg tan1 = b->dot[dotN].abs.arg(b->dot[imod(dotN-2)].abs);
		const Arg tan2 = b->dot[imod(dotN+1)].abs.arg(b->dot[imod(dotN-1)].abs);
		const double exc = -(b->dot[imod(dotN-1)].abs-b->dot[dotN].abs)^(t->p-b->dot[dotN].abs);
		if(exc < 0 && exc > -b->size){
			auto& c1 = conn[conS];
			auto& c2 = b->con[6+b->conS2];
			c1->p = t->p;
			c1->exc = -exc;
			c1->num = b->num;
			c1->type = ObjType::D;
			c1->weight = b->weight;
			c1->arg = arg+PI;
			c1->color = b->color;
			c1->side = t->side;
			c1->pairP = b->p;
			c1->pairV = b->v;
			
			c2->p = t->p;
			c2->dist = c2->p.dist(b->p);
			c2->exc = -exc;
			c2->arg = arg;
			c2->tan = (1.0-s)*tan1+s*tan2;
			c2->num = num;
			c2->type = ObjType::O;
			c2->side = t->side;
			
			conS++;
			b->conS2++;
			
			std::cout << "?" << *c1 << "\n" << *c2 << "\n";
		}
		// この場合は辺に当たる
	}else if(t->side%2==0){
		const Arg arg = t->arg+PI;
		int dotN = imod(round(arg.val()*dotL/PI2));
		// 壁に垂直な向きへの長さが一番大きい点を調べる
		if(b->dot[imod(dotN+1)].rel*pol(arg) > b->dot[imod(dotN-1)].rel*pol(arg)){
			while(b->dot[imod(dotN+1)].rel*pol(arg) > b->dot[dotN].rel*pol(arg)){
				dotN = imod(dotN+1);
			}
		}else{
			while(b->dot[imod(dotN-1)].rel*pol(arg) > b->dot[dotN].rel*pol(arg)){
				dotN = imod(dotN-1);
			}
		}
		if((b->dot[dotN].abs-t->p)*pol(arg) >= 0.0){
			auto& c1 = conn[conS];
			auto& c2 = b->con[6+b->conS2];
			if(std::abs(b->dot[dotN].abs.x-b->p.x) < 1.0e-6){
				c1->p = c2->p = t->p;
			}else if(tan(arg) < 1.0e-6){
				c1->p.x = c2->p.x = t->p.x;
				c1->p.y = c2->p.y = b->p.y;
			}else{
				const double a1 = (b->dot[dotN].abs.y-b->p.y)/(b->dot[dotN].abs.x-b->p.x);
				const double a3 = -1.0/tan(arg);
				c1->p.x = (a1*b->p.x-b->p.y-a3*t->p.x+t->p.y)/(a1-a3);
				c1->p.y = a1*(c1->p.x-b->p.x)+b->p.y;
				c2->p.x = (a1*b->p.x-b->p.y-a3*t->p.x+t->p.y)/(a1-a3);
				c2->p.y = a1*(c2->p.x-b->p.x)+b->p.y;
			}
			c1->exc = (b->dot[dotN].abs-c1->p)*pol(PI-arg);
			c1->num = b->num;
			c1->type = ObjType::D;
			c1->weight = b->weight;
			c1->arg = arg;
			c1->color = b->color;
			c1->side = t->side;
			c1->pairP = b->p;
			c1->pairV = b->v;
			
			c2->dist = c2->p.dist(b->p);
			c2->exc = (b->dot[dotN].abs-c2->p)*pol(PI-arg);
			c2->arg = c2->p.arg(b->p);
			c2->tan = arg+PI_2;
			c2->num = num;
			c2->type = ObjType::O;
			c2->side = t->side;
			
			conS++;
			b->conS2++;
			
			std::cout << "?" << *c1 << "\n" << *c2 << "\n";
		}
	}else{
		printf("$\n");
	}
}