Beispiel #1
0
/* This does the case of tiling with non simple tiles.  In this case, the
 * tiles may overlap and so we really need to do blending within the existing
 * buffer.  This needs some serious optimization. */
void
tile_rect_trans_blend(int xmin, int ymin, int xmax, int ymax,
                      int px, int py, const gx_color_tile *ptile,
                      gx_pattern_trans_t *fill_trans_buffer)
{
    int kk, jj, ii, h, w;
    int buff_out_y_offset, buff_out_x_offset;
    unsigned char *buff_out, *buff_in;
    unsigned char *buff_ptr, *row_ptr_in, *row_ptr_out;
    unsigned char *tile_ptr;
    int in_row_offset;
    int dx, dy;
    byte src[PDF14_MAX_PLANES];
    byte dst[PDF14_MAX_PLANES];
    int tile_width  = ptile->ttrans->width;
    int tile_height = ptile->ttrans->height;
    int num_chan    = ptile->ttrans->n_chan;  /* Includes alpha */

    /* Update the bbox in the topmost stack entry to reflect the fact that we
     * have drawn into it. FIXME: This makes the groups too large! */
    if (fill_trans_buffer->dirty->p.x > xmin)
        fill_trans_buffer->dirty->p.x = xmin;
    if (fill_trans_buffer->dirty->p.y > ymin)
        fill_trans_buffer->dirty->p.y = ymin;
    if (fill_trans_buffer->dirty->q.x < xmax)
        fill_trans_buffer->dirty->q.x = xmax;
    if (fill_trans_buffer->dirty->q.y < ymax)
        fill_trans_buffer->dirty->q.y = ymax;
    buff_out_y_offset = ymin - fill_trans_buffer->rect.p.y;
    buff_out_x_offset = xmin - fill_trans_buffer->rect.p.x;

    buff_out = fill_trans_buffer->transbytes +
        buff_out_y_offset * fill_trans_buffer->rowstride +
        buff_out_x_offset;

    buff_in = ptile->ttrans->transbytes;

    h = ymax - ymin;
    w = xmax - xmin;

    if (h <= 0 || w <= 0) return;

    /* Calc dx, dy within the entire (conceptual) input tile. */
    dx = (xmin + px) % tile_width;
    dy = (ymin + py) % tile_height;

    for (jj = 0; jj < h; jj++){

        in_row_offset = (jj + dy) % ptile->ttrans->height;
        if (in_row_offset >= ptile->ttrans->rect.q.y)
            continue;
        in_row_offset -= ptile->ttrans->rect.p.y;
        if (in_row_offset < 0)
            continue;
        row_ptr_in = buff_in + in_row_offset * ptile->ttrans->rowstride;

        row_ptr_out = buff_out + jj * fill_trans_buffer->rowstride;

        for (ii = 0; ii < w; ii++) {
            int x_in_offset = (dx + ii) % ptile->ttrans->width;

            if (x_in_offset >= ptile->ttrans->rect.q.x)
                continue;
            x_in_offset -= ptile->ttrans->rect.p.x;
            if (x_in_offset < 0)
                continue;
            tile_ptr = row_ptr_in + x_in_offset;
            buff_ptr = row_ptr_out + ii;

            /* We need to blend here.  The blending mode from the current
               imager state is used.
            */

            /* The color values. This needs to be optimized */
            for (kk = 0; kk < num_chan; kk++) {
                dst[kk] = *(buff_ptr + kk * fill_trans_buffer->planestride);
                src[kk] = *(tile_ptr + kk * ptile->ttrans->planestride);
            }

            /* Blend */
            art_pdf_composite_pixel_alpha_8(dst, src,
                                            ptile->ttrans->n_chan-1,
                                            ptile->ttrans->blending_mode,
                                            ptile->ttrans->blending_procs);

            /* Store the color values */
            for (kk = 0; kk < num_chan; kk++) {
                *(buff_ptr + kk * fill_trans_buffer->planestride) = dst[kk];
            }
        }
    }

    /* If the group we are filling has a shape plane fill that now */
    /* Note:  Since this was a virgin group push we can just blast it with
     * 255 */
    if (fill_trans_buffer->has_shape) {
        buff_ptr = buff_out + fill_trans_buffer->n_chan * fill_trans_buffer->planestride;

        for (jj = 0; jj < h; jj++) {
            memset(buff_ptr, 255, w);
            buff_ptr += fill_trans_buffer->rowstride;
        }
    }
}
Beispiel #2
0
/* This does the case of tiling with non simple tiles.  In this case, the tiles may overlap and
   so we really need to do blending within the existing buffer.  This needs some serious optimization. */
void
tile_rect_trans_blend(int xmin, int ymin, int xmax, int ymax, int px, int py, const gx_color_tile *ptile,
            gx_pattern_trans_t *fill_trans_buffer)
{
    int kk, jj, ii, h, w, buff_y_offset, buff_x_offset;
    unsigned char *buff_out, *buff_in;
    unsigned char *buff_ptr, *row_ptr_in, *row_ptr_out;
    unsigned char *tile_ptr;
    int in_row_offset;
    int tile_width = ptile->ttrans->width;
    int tile_height = ptile->ttrans->height;
    int dx, dy;
    byte src[PDF14_MAX_PLANES];
    byte dst[PDF14_MAX_PLANES];
    int num_chan = ptile->ttrans->n_chan;  /* Includes alpha */

    buff_y_offset = ymin - fill_trans_buffer->rect.p.y;
    buff_x_offset = xmin - fill_trans_buffer->rect.p.x;

    buff_out = fill_trans_buffer->transbytes +
        buff_y_offset * fill_trans_buffer->rowstride +
        buff_x_offset;

    buff_in = ptile->ttrans->transbytes;

    h = ymax - ymin;
    w = xmax - xmin;

    dx = (xmin + px) % tile_width;
    dy = (ymin + py) % tile_height;

    for (jj = 0; jj < h; jj++){

        in_row_offset = (jj + dy) % ptile->ttrans->height;
        row_ptr_in = buff_in + in_row_offset * ptile->ttrans->rowstride;

        row_ptr_out = buff_out + jj * fill_trans_buffer->rowstride;

        for (ii = 0; ii < w; ii++) {

            tile_ptr = row_ptr_in + (dx + ii) % ptile->ttrans->width;
            buff_ptr = row_ptr_out + ii;

            /* We need to blend here.  The blending mode from the current
               imager state is used.
            */

            /* The color values. This needs to be optimized */

            for (kk = 0; kk < num_chan; kk++){

                dst[kk] = *(buff_ptr + kk * fill_trans_buffer->planestride);
                src[kk] = *(tile_ptr + kk * ptile->ttrans->planestride);

            }

            /* Blend */

           art_pdf_composite_pixel_alpha_8(dst, src, ptile->ttrans->n_chan-1,
                                         ptile->ttrans->blending_mode, ptile->ttrans->blending_procs);

            /* Store the color values */

            for (kk = 0; kk < num_chan; kk++){

                *(buff_ptr + kk * fill_trans_buffer->planestride) = dst[kk];

            }

        }

    }

    /* If the group we are filling has a shape plane fill that now */
    /* Note:  Since this was a virgin group push we can just blast it with 255 */

    if (fill_trans_buffer->has_shape) {

        buff_ptr = buff_out + fill_trans_buffer->n_chan * fill_trans_buffer->planestride;

        for (jj = 0; jj < h; jj++){

            memset(buff_ptr, 255, w);
            buff_ptr += fill_trans_buffer->rowstride;

        }

    }

}