do_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
                       gx_color_index color, const gx_device_color *pdc,
                       bool devn)
{
    pdf14_device *pdev = (pdf14_device *)dev;
    pdf14_buf *buf = pdev->ctx->stack;
    int j;
    byte *dst_ptr;
    byte src[PDF14_MAX_PLANES];
    gs_blend_mode_t blend_mode = pdev->blend_mode;
    bool additive = pdev->ctx->additive;
    int rowstride = buf->rowstride;
    int planestride = buf->planestride;
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG; /* Quite compiler */
    bool has_alpha_g = buf->has_alpha_g;
    bool has_shape = buf->has_shape;
    bool has_tags = buf->has_tags;
    int num_chan = buf->n_chan;
    int num_comp = num_chan - 1;
    int shape_off = num_chan * planestride;
    int alpha_g_off = shape_off + (has_shape ? planestride : 0);
    int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
    bool overprint = pdev->overprint;
    gx_color_index drawn_comps = pdev->drawn_comps;
    byte shape = 0; /* Quiet compiler. */
    byte src_alpha;
    const gx_color_index mask = ((gx_color_index)1 << 8) - 1;
    const int shift = 8;
    int num_spots = buf->num_spots;
    int first_blend_spot = num_comp;
    pdf14_mark_fill_rect_fn fn;
    bool isolated = buf->isolated;

    if (num_spots > 0 && !blend_valid_for_spot(blend_mode))
        first_blend_spot = num_comp - num_spots;
    if (blend_mode == BLEND_MODE_Normal)
        first_blend_spot = 0;

    if (buf->data == NULL)
        return 0;
    /* NB: gx_color_index is 4 or 8 bytes */
#if 0
    if (sizeof(color) <= sizeof(ulong))
        if_debug8m('v', dev->memory,
                   "[v]pdf14_mark_fill_rectangle, (%d, %d), %d x %d color = %lx  bm %d, nc %d, overprint %d\n",
                   x, y, w, h, (ulong)color, blend_mode, num_chan, overprint);
    else
        if_debug9m('v', dev->memory,
                   "[v]pdf14_mark_fill_rectangle, (%d, %d), %d x %d color = %08lx%08lx  bm %d, nc %d, overprint %d\n",
                   x, y, w, h,
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
                   blend_mode, num_chan, overprint);
#endif
    /*
     * Unpack the gx_color_index values.  Complement the components for subtractive
     * color spaces.
     */
    if (has_tags) {
        curr_tag = (color >> (num_comp*8)) & 0xff;
    }
    if (devn) {
        if (additive) {
            for (j = 0; j < (num_comp - num_spots); j++) {
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
            }
            for (j = 0; j < num_spots; j++) {
                src[j + num_comp - num_spots] =
                    255 - ((pdc->colors.devn.values[j + num_comp - num_spots]) >> shift & mask);
            }
        } else {
            for (j = 0; j < num_comp; j++) {
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
            }
        }
    } else
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
    if (has_shape)
        shape = (byte)floor (255 * pdev->shape + 0.5);
    /* Fit the mark into the bounds of the buffer */
    if (x < buf->rect.p.x) {
        w += x - buf->rect.p.x;
        x = buf->rect.p.x;
    }
    if (y < buf->rect.p.y) {
      h += y - buf->rect.p.y;
      y = buf->rect.p.y;
    }
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
    /* Update the dirty rectangle with the mark */
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
    dst_ptr = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
    src_alpha = 255-src_alpha;
    shape = 255-shape;
    if (!has_alpha_g)
        alpha_g_off = 0;
    if (!has_shape)
        shape_off = 0;
    if (!has_tags)
        tag_off = 0;
    rowstride -= w;
    /* The num_comp == 1 && additive case is very common (mono output
     * devices no spot support), so we optimise that specifically here. */
    if (src[num_comp] == 0)
        fn = mark_fill_rect_alpha0;
    else if (additive && num_spots == 0) {
        if (num_comp == 1) {
            if (blend_mode == BLEND_MODE_Normal) {
                if (tag_off == 0 && shape_off == 0 &&  alpha_g_off == 0)
                    fn = mark_fill_rect_add1_no_spots_fast;
                else
                    fn = mark_fill_rect_add1_no_spots_normal;
            } else
                fn = mark_fill_rect_add1_no_spots;
        } else if (tag_off == 0 && shape_off == 0 && blend_mode == BLEND_MODE_Normal) {
            if (alpha_g_off == 0) {
                if (num_comp == 3)
                    fn = mark_fill_rect_add3_common;
                else
                    fn = mark_fill_rect_add_nospots_common_no_alpha_g;
            } else
                fn = mark_fill_rect_add_nospots_common;
        } else
            fn = mark_fill_rect_add_nospots;
    } else if (!additive && num_spots == 0 && num_comp == 4 && num_spots == 0 &&
        first_blend_spot == 0 && blend_mode == BLEND_MODE_Normal &&
        !overprint && tag_off == 0 && alpha_g_off == 0 && shape_off == 0)
        fn = mark_fill_rect_sub4_fast;
    else
        fn = mark_fill_rect;

    fn(w, h, dst_ptr, src, num_comp, num_spots, first_blend_spot, src_alpha,
       rowstride, planestride, additive, pdev, blend_mode, overprint,
       drawn_comps, tag_off, curr_tag, alpha_g_off, shape_off, shape, isolated);

#if 0
/* #if RAW_DUMP */
    /* Dump the current buffer to see what we have. */

    if(global_index/10.0 == (int) (global_index/10.0) )
        dump_raw_buffer(pdev->ctx->mem,
                        pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
                        pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
                        pdev->ctx->stack->n_planes,
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
                        "Draw_Rect", pdev->ctx->stack->data, pdev->ctx->stack->deep);

    global_index++;
#endif
    return 0;
}