/*
 * DIB driver GDI objects.
 *
 * Copyright 2011 Huw Davies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <assert.h>
#include <stdlib.h>

#include "gdi_private.h"
#include "dibdrv.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dib);

/*
 *
 * Decompose the 16 ROP2s into an expression of the form
 *
 * D = (D & A) ^ X
 *
 * Where A and X depend only on P (and so can be precomputed).
 *
 *                                       A    X
 *
 * R2_BLACK         0                    0    0
 * R2_NOTMERGEPEN   ~(D | P)            ~P   ~P
 * R2_MASKNOTPEN    ~P & D              ~P    0
 * R2_NOTCOPYPEN    ~P                   0   ~P
 * R2_MASKPENNOT    P & ~D               P    P
 * R2_NOT           ~D                   1    1
 * R2_XORPEN        P ^ D                1    P
 * R2_NOTMASKPEN    ~(P & D)             P    1
 * R2_MASKPEN       P & D                P    0
 * R2_NOTXORPEN     ~(P ^ D)             1   ~P
 * R2_NOP           D                    1    0
 * R2_MERGENOTPEN   ~P | D               P   ~P
 * R2_COPYPEN       P                    0    P
 * R2_MERGEPENNOT   P | ~D              ~P    1
 * R2_MERGEPEN      P | D               ~P    P
 * R2_WHITE         1                    0    1
 *
 */

/* A = (P & A1) ^ A2 */
#define ZERO  { 0u,  0u}
#define ONE   { 0u, ~0u}
#define P     {~0u,  0u}
#define NOT_P {~0u, ~0u}

static const DWORD rop2_and_array[16][2] =
{
    ZERO, NOT_P, NOT_P, ZERO,
    P,    ONE,   ONE,   P,
    P,    ONE,   ONE,   P,
    ZERO, NOT_P, NOT_P, ZERO
};

/* X = (P & X1) ^ X2 */
static const DWORD rop2_xor_array[16][2] =
{
    ZERO, NOT_P, ZERO, NOT_P,
    P,    ONE,   P,    ONE,
    ZERO, NOT_P, ZERO, NOT_P,
    P,    ONE,   P,    ONE
};

#undef NOT_P
#undef P
#undef ONE
#undef ZERO

void get_rop_codes(INT rop, struct rop_codes *codes)
{
    /* NB The ROP2 codes start at one and the arrays are zero-based */
    codes->a1 = rop2_and_array[rop-1][0];
    codes->a2 = rop2_and_array[rop-1][1];
    codes->x1 = rop2_xor_array[rop-1][0];
    codes->x2 = rop2_xor_array[rop-1][1];
}

static inline void calc_and_xor_masks(INT rop, DWORD color, DWORD *and, DWORD *xor)
{
    struct rop_codes codes;
    get_rop_codes( rop, &codes );

    *and = (color & codes.a1) ^ codes.a2;
    *xor = (color & codes.x1) ^ codes.x2;
}

static inline void calc_rop_masks(INT rop, DWORD color, rop_mask *masks)
{
    calc_and_xor_masks( rop, color, &masks->and, &masks->xor );
}

static inline RGBQUAD rgbquad_from_colorref(COLORREF c)
{
    RGBQUAD ret;

    ret.rgbRed      = GetRValue(c);
    ret.rgbGreen    = GetGValue(c);
    ret.rgbBlue     = GetBValue(c);
    ret.rgbReserved = 0;
    return ret;
}

static inline BOOL rgbquad_equal(const RGBQUAD *a, const RGBQUAD *b)
{
    if(a->rgbRed   == b->rgbRed   &&
       a->rgbGreen == b->rgbGreen &&
       a->rgbBlue  == b->rgbBlue)
        return TRUE;
    return FALSE;
}

COLORREF make_rgb_colorref( HDC hdc, dib_info *dib, COLORREF color, BOOL *got_pixel, DWORD *pixel )
{
    *pixel = 0;
    *got_pixel = FALSE;

    if (color & (1 << 24))  /* PALETTEINDEX */
    {
        HPALETTE pal = GetCurrentObject( hdc, OBJ_PAL );
        PALETTEENTRY pal_ent;

        if (!GetPaletteEntries( pal, LOWORD(color), 1, &pal_ent ))
            GetPaletteEntries( pal, 0, 1, &pal_ent );
        return RGB( pal_ent.peRed, pal_ent.peGreen, pal_ent.peBlue );
    }

    if (color >> 16 == 0x10ff)  /* DIBINDEX */
    {
        const RGBQUAD *color_table = get_dib_color_table( dib );
        WORD index = LOWORD( color );
        *got_pixel = TRUE;
        if (!color_table || index >= (1 << dib->bit_count)) return 0;
        *pixel = index;
        return RGB( color_table[index].rgbRed, color_table[index].rgbGreen, color_table[index].rgbBlue );
    }

    return color & 0xffffff;
}

/******************************************************************
 *                   get_pixel_color
 *
 * 1 bit bitmaps map the fg/bg colors as follows:
 * If the fg colorref exactly matches one of the color table entries then
 * that entry is the fg color and the other is the bg.
 * Otherwise the bg color is mapped to the closest entry in the table and
 * the fg takes the other one.
 */
DWORD get_pixel_color( dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup )
{
    RGBQUAD fg_quad;
    BOOL got_pixel;
    DWORD pixel;
    COLORREF rgb_ref;
    const RGBQUAD *color_table;

    rgb_ref = make_rgb_colorref( pdev->dev.hdc, &pdev->dib, color, &got_pixel, &pixel );
    if (got_pixel) return pixel;

    if (pdev->dib.bit_count != 1 || !mono_fixup)
        return pdev->dib.funcs->colorref_to_pixel( &pdev->dib, rgb_ref );

    color_table = get_dib_color_table( &pdev->dib );
    fg_quad = rgbquad_from_colorref( rgb_ref );
    if(rgbquad_equal(&fg_quad, color_table))
        return 0;
    if(rgbquad_equal(&fg_quad, color_table + 1))
        return 1;

    pixel = get_pixel_color( pdev, GetBkColor(pdev->dev.hdc), FALSE );
    if (color == GetBkColor(pdev->dev.hdc)) return pixel;
    else return !pixel;
}

/***************************************************************************
 *                get_color_masks
 *
 * Returns the color masks unless the dib is 1 bpp.  In this case since
 * there are several fg sources (pen, brush, text) we take as bg the inverse
 * of the relevant fg color (which is always set up correctly).
 */
static inline void get_color_masks( dibdrv_physdev *pdev, UINT rop, COLORREF colorref,
                                    INT bkgnd_mode, rop_mask *fg_mask, rop_mask *bg_mask )
{
    DWORD color = get_pixel_color( pdev, colorref, TRUE );

    calc_rop_masks( rop, color, fg_mask );

    if (bkgnd_mode == TRANSPARENT)
    {
        bg_mask->and = ~0u;
        bg_mask->xor = 0;
        return;
    }

    if (pdev->dib.bit_count != 1) color = get_pixel_color( pdev, GetBkColor(pdev->dev.hdc), FALSE );
    else if (colorref != GetBkColor(pdev->dev.hdc)) color = !color;

    calc_rop_masks( rop, color, bg_mask );
}

static inline void order_end_points(int *s, int *e)
{
    if(*s > *e)
    {
        int tmp;
        tmp = *s + 1;
        *s = *e + 1;
        *e = tmp;
    }
}

#define Y_INCREASING_MASK 0x0f
#define X_INCREASING_MASK 0xc3
#define X_MAJOR_MASK      0x99
#define POS_SLOPE_MASK    0x33

static inline BOOL is_xmajor(DWORD octant)
{
    return octant & X_MAJOR_MASK;
}

static inline BOOL is_pos_slope(DWORD octant)
{
    return octant & POS_SLOPE_MASK;
}

static inline BOOL is_x_increasing(DWORD octant)
{
    return octant & X_INCREASING_MASK;
}

static inline BOOL is_y_increasing(DWORD octant)
{
    return octant & Y_INCREASING_MASK;
}

/**********************************************************************
 *                  get_octant_number
 *
 * Return the octant number starting clockwise from the +ve x-axis.
 */
static inline int get_octant_number(int dx, int dy)
{
    if(dy > 0)
        if(dx > 0)
            return ( dx >  dy) ? 1 : 2;
        else
            return (-dx >  dy) ? 4 : 3;
    else
        if(dx < 0)
            return (-dx > -dy) ? 5 : 6;
        else
            return ( dx > -dy) ? 8 : 7;
}

static inline DWORD get_octant_mask(int dx, int dy)
{
    return 1 << (get_octant_number(dx, dy) - 1);
}

static inline int get_bias( DWORD mask )
{
    /* Octants 3, 5, 6 and 8 take a bias */
    return (mask & 0xb4) ? 1 : 0;
}

#define OUT_LEFT    1
#define OUT_RIGHT   2
#define OUT_TOP     4
#define OUT_BOTTOM  8

static inline DWORD calc_outcode(const POINT *pt, const RECT *clip)
{
    DWORD out = 0;
    if(pt->x < clip->left)         out |= OUT_LEFT;
    else if(pt->x >= clip->right)  out |= OUT_RIGHT;
    if(pt->y < clip->top)          out |= OUT_TOP;
    else if(pt->y >= clip->bottom) out |= OUT_BOTTOM;

    return out;
}

/* crop coordinates to a reasonable range to avoid overflows in calculations */
static inline POINT crop_coords( POINT pt )
{
    if (pt.x >= 0x10000000 || pt.x <= -0x10000000 || pt.y >= 0x10000000 || pt.y <= -0x10000000)
    {
        pt.x /= 8;
        pt.y /= 8;
    }
    return pt;
}

static void init_bres_params( const POINT *start, const POINT *end, bres_params *clip_params,
                              struct line_params *line_params, RECT *rect )
{
    INT dx = end->x - start->x, dy = end->y - start->y;
    INT abs_dx = abs(dx), abs_dy = abs(dy);

    clip_params->dx = abs_dx;
    clip_params->dy = abs_dy;
    clip_params->octant = get_octant_mask(dx, dy);
    clip_params->bias   = get_bias( clip_params->octant );

    line_params->bias    = clip_params->bias;
    line_params->x_major = is_xmajor( clip_params->octant );
    line_params->x_inc   = is_x_increasing( clip_params->octant ) ? 1 : -1;
    line_params->y_inc   = is_y_increasing( clip_params->octant ) ? 1 : -1;

    if (line_params->x_major)
    {
        line_params->err_add_1 = 2 * abs_dy - 2 * abs_dx;
        line_params->err_add_2 = 2 * abs_dy;
    }
    else
    {
        line_params->err_add_1 = 2 * abs_dx - 2 * abs_dy;
        line_params->err_add_2 = 2 * abs_dx;
    }

    rect->left   = min( start->x, end->x );
    rect->top    = min( start->y, end->y );
    rect->right  = max( start->x, end->x ) + 1;
    rect->bottom = max( start->y, end->y ) + 1;
}

/******************************************************************************
 *                clip_line
 *
 * Clips the start and end points to a rectangle.
 *
 * Note, this treats the end point like the start point.  If the
 * caller doesn't want it displayed, it should exclude it.  If the end
 * point is clipped out, then the likelihood is that the new end point
 * should be displayed.
 *
 * Returns 0 if totally excluded, 1 if partially clipped and 2 if unclipped.
 *
 * This derivation is based on the comments in X.org's xserver/mi/mizerclip.c,
 * however the Bresenham error term is defined differently so the equations
 * will also differ.
 *
 * For x major lines we have 2dy >= err + bias > 2dy - 2dx
 *                           0   >= err + bias - 2dy > -2dx
 *
 * Note dx, dy, m and n are all +ve.
 *
 * Moving the start pt from x1 to x1 + m, we need to figure out y1 + n.
 *                     err = 2dy - dx + 2mdy - 2ndx
 *                      0 >= 2dy - dx + 2mdy - 2ndx + bias - 2dy > -2dx
 *                      0 >= 2mdy - 2ndx + bias - dx > -2dx
 *                      which of course will give exactly one solution for n,
 *                      so looking at the >= inequality
 *                      n >= (2mdy + bias - dx) / 2dx
 *                      n = ceiling((2mdy + bias - dx) / 2dx)
 *                        = (2mdy + bias + dx - 1) / 2dx (assuming division truncation)
 *
 * Moving start pt from y1 to y1 + n we need to figure out x1 + m - there may be several
 * solutions we pick the one that minimizes m (ie that first unlipped pt). As above:
 *                     0 >= 2mdy - 2ndx + bias - dx > -2dx
 *                  2mdy > 2ndx - bias - dx
 *                     m > (2ndx - bias - dx) / 2dy
 *                     m = floor((2ndx - bias - dx) / 2dy) + 1
 *                     m = (2ndx - bias - dx) / 2dy + 1
 *
 * Moving end pt from x2 to x2 - m, we need to figure out y2 - n
 *                  err = 2dy - dx + 2(dx - m)dy - 2(dy - n)dx
 *                      = 2dy - dx - 2mdy + 2ndx
 *                   0 >= 2dy - dx - 2mdy + 2ndx + bias - 2dy > -2dx
 *                   0 >= 2ndx - 2mdy + bias - dx > -2dx
 *                   again exactly one solution.
 *                   2ndx <= 2mdy - bias + dx
 *                   n = floor((2mdy - bias + dx) / 2dx)
 *                     = (2mdy - bias + dx) / 2dx
 *
 * Moving end pt from y2 to y2 - n when need x2 - m this time maximizing x2 - m so
 * mininizing m to include all of the points at y = y2 - n.  As above:
 *                  0 >= 2ndx - 2mdy + bias - dx > -2dx
 *               2mdy >= 2ndx + bias - dx
 *                   m = ceiling((2ndx + bias - dx) / 2dy)
 *                     = (2ndx + bias - dx - 1) / 2dy + 1
 *
 * For y major lines, symmetry (dx <-> dy and swap the cases over) gives:
 *
 * Moving start point from y1 to y1 + n find x1 + m
 *                     m = (2ndx + bias + dy - 1) / 2dy
 *
 * Moving start point from x1 to x1 + m find y1 + n
 *                     n = (2mdy - bias - dy) / 2ndx + 1
 *
 * Moving end point from y2 to y2 - n find x1 - m
 *                     m = (2ndx - bias + dy) / 2dy
 *
 * Moving end point from x2 to x2 - m find y2 - n
 *                     n = (2mdy + bias - dy - 1) / 2dx + 1
 */
int clip_line(const POINT *start, const POINT *end, const RECT *clip,
              const bres_params *params, POINT *pt1, POINT *pt2)
{

    INT64 m, n;  /* 64-bit to avoid overflows (FIXME: find a more efficient way) */
    BOOL clipped = FALSE;
    DWORD start_oc, end_oc;
    const int bias = params->bias;
    const unsigned int dx = params->dx;
    const unsigned int dy = params->dy;
    const unsigned int two_dx = params->dx * 2;
    const unsigned int two_dy = params->dy * 2;
    const BOOL xmajor = is_xmajor(params->octant);
    const BOOL neg_slope = !is_pos_slope(params->octant);

    *pt1 = *start;
    *pt2 = *end;

    start_oc = calc_outcode(start, clip);
    end_oc = calc_outcode(end, clip);

    while(1)
    {
        if(start_oc == 0 && end_oc == 0) return clipped ? 1 : 2; /* trivial accept */
        if(start_oc & end_oc)            return 0; /* trivial reject */

        clipped = TRUE;
        if(start_oc & OUT_LEFT)
        {
            m = clip->left - start->x;
            if(xmajor)
                n = (m * two_dy + bias + dx - 1) / two_dx;
            else
                n = (m * two_dy - bias - dy) / two_dx + 1;

            pt1->x = clip->left;
            if(neg_slope) n = -n;
            pt1->y = start->y + n;
            start_oc = calc_outcode(pt1, clip);
        }
        else if(start_oc & OUT_RIGHT)
        {
            m = start->x - clip->right + 1;
            if(xmajor)
                n = (m * two_dy + bias + dx - 1) / two_dx;
            else
                n = (m * two_dy - bias - dy) / two_dx + 1;

            pt1->x = clip->right - 1;
            if(neg_slope) n = -n;
            pt1->y = start->y - n;
            start_oc = calc_outcode(pt1, clip);
        }
        else if(start_oc & OUT_TOP)
        {
            n = clip->top - start->y;
            if(xmajor)
                m = (n * two_dx - bias - dx) / two_dy + 1;
            else
                m = (n * two_dx + bias + dy - 1) / two_dy;

            pt1->y = clip->top;
            if(neg_slope) m = -m;
            pt1->x = start->x + m;
            start_oc = calc_outcode(pt1, clip);
        }
        else if(start_oc & OUT_BOTTOM)
        {
            n = start->y - clip->bottom + 1;
            if(xmajor)
                m = (n * two_dx - bias - dx) / two_dy + 1;
            else
                m = (n * two_dx + bias + dy - 1) / two_dy;

            pt1->y = clip->bottom - 1;
            if(neg_slope) m = -m;
            pt1->x = start->x - m;
            start_oc = calc_outcode(pt1, clip);
        }
        else if(end_oc & OUT_LEFT)
        {
            m = clip->left - end->x;
            if(xmajor)
                n = (m * two_dy - bias + dx) / two_dx;
            else
                n = (m * two_dy + bias - dy - 1) / two_dx + 1;

            pt2->x = clip->left;
            if(neg_slope) n = -n;
            pt2->y = end->y + n;
            end_oc = calc_outcode(pt2, clip);
        }
        else if(end_oc & OUT_RIGHT)
        {
            m = end->x - clip->right + 1;
            if(xmajor)
                n = (m * two_dy - bias + dx) / two_dx;
            else
                n = (m * two_dy + bias - dy - 1) / two_dx + 1;

            pt2->x = clip->right - 1;
            if(neg_slope) n = -n;
            pt2->y = end->y - n;
            end_oc = calc_outcode(pt2, clip);
        }
        else if(end_oc & OUT_TOP)
        {
            n = clip->top - end->y;
            if(xmajor)
                m = (n * two_dx + bias - dx - 1) / two_dy + 1;
            else
                m = (n * two_dx - bias + dy) / two_dy;

            pt2->y = clip->top;
            if(neg_slope) m = -m;
            pt2->x = end->x + m;
            end_oc = calc_outcode(pt2, clip);
        }
        else if(end_oc & OUT_BOTTOM)
        {
            n = end->y - clip->bottom + 1;
            if(xmajor)
                m = (n * two_dx + bias - dx - 1) / two_dy + 1;
            else
                m = (n * two_dx - bias + dy) / two_dy;

            pt2->y = clip->bottom - 1;
            if(neg_slope) m = -m;
            pt2->x = end->x - m;
            end_oc = calc_outcode(pt2, clip);
        }
    }
}

static void bres_line_with_bias(const POINT *start, const struct line_params *params,
                                void (* callback)(dibdrv_physdev*,INT,INT), dibdrv_physdev *pdev)
{
    POINT pt = *start;
    int len = params->length, err = params->err_start;

    if (params->x_major)
    {
        while(len--)
        {
            callback(pdev, pt.x, pt.y);
            if (err + params->bias > 0)
            {
                pt.y += params->y_inc;
                err += params->err_add_1;
            }
            else err += params->err_add_2;
            pt.x += params->x_inc;
        }
    }
    else
    {
        while(len--)
        {
            callback(pdev, pt.x, pt.y);
            if (err + params->bias > 0)
            {
                pt.x += params->x_inc;
                err += params->err_add_1;
            }
            else err += params->err_add_2;
            pt.y += params->y_inc;
        }
    }
}

static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end, DWORD and, DWORD xor)
{
    struct clipped_rects clipped_rects;
    RECT rect;
    int i;

    if(start->y == end->y)
    {
        rect.left   = start->x;
        rect.top    = start->y;
        rect.right  = end->x;
        rect.bottom = end->y + 1;
        order_end_points(&rect.left, &rect.right);
        if (!get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects )) return TRUE;
        pdev->dib.funcs->solid_rects(&pdev->dib, clipped_rects.count, clipped_rects.rects, and, xor);
    }
    else if(start->x == end->x)
    {
        rect.left   = start->x;
        rect.top    = start->y;
        rect.right  = end->x + 1;
        rect.bottom = end->y;
        order_end_points(&rect.top, &rect.bottom);
        if (!get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects )) return TRUE;
        pdev->dib.funcs->solid_rects(&pdev->dib, clipped_rects.count, clipped_rects.rects, and, xor);
    }
    else
    {
        bres_params clip_params;
        struct line_params line_params;
        POINT p1 = crop_coords( *start ), p2 = crop_coords( *end );

        init_bres_params( &p1, &p2, &clip_params, &line_params, &rect );
        if (!get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects )) return TRUE;
        for (i = 0; i < clipped_rects.count; i++)
        {
            POINT clipped_start, clipped_end;
            int clip_status;

            clip_status = clip_line( &p1, &p2, clipped_rects.rects + i, &clip_params, &clipped_start, &clipped_end);
            if(clip_status)
            {
                int m = abs(clipped_start.x - p1.x);
                int n = abs(clipped_start.y - p1.y);

                if (line_params.x_major)
                {
                    line_params.err_start = 2 * clip_params.dy - clip_params.dx
                                          + m * 2 * clip_params.dy - n * 2 * clip_params.dx;
                    line_params.length = abs( clipped_end.x - clipped_start.x ) + 1;
                }
                else
                {
                    line_params.err_start = 2 * clip_params.dx - clip_params.dy
                                          + n * 2 * clip_params.dx - m * 2 * clip_params.dy;
                    line_params.length = abs( clipped_end.y - clipped_start.y ) + 1;
                }

                if (clipped_end.x == p2.x && clipped_end.y == p2.y) line_params.length--;

                pdev->dib.funcs->solid_line( &pdev->dib, &clipped_start, &line_params, and, xor );

                if(clip_status == 2) break; /* completely unclipped, so we can finish */
            }
        }
    }
    free_clipped_rects( &clipped_rects );
    return TRUE;
}

static void solid_line_region( const dib_info *dib, const POINT *start, const struct line_params *params,
                               HRGN region )
{
    int len, err = params->err_start;
    RECT rect;

    rect.left   = start->x;
    rect.top    = start->y;
    rect.right  = start->x + 1;
    rect.bottom = start->y + 1;

    if (params->x_major)
    {
        if (params->x_inc > 0)
        {
            for (len = params->length; len; len--, rect.right++)
            {
                if (err + params->bias > 0)
                {
                    add_rect_to_region( region, &rect );
                    rect.left = rect.right;
                    rect.top += params->y_inc;
                    rect.bottom += params->y_inc;
                    err += params->err_add_1;
                }
                else err += params->err_add_2;
            }
        }
        else
        {
            for (len = params->length; len; len--, rect.left--)
            {
                if (err + params->bias > 0)
                {
                    add_rect_to_region( region, &rect );
                    rect.right = rect.left;
                    rect.top += params->y_inc;
                    rect.bottom += params->y_inc;
                    err += params->err_add_1;
                }
                else err += params->err_add_2;
            }
        }
    }
    else
    {
        if (params->y_inc > 0)
        {
            for (len = params->length; len; len--, rect.bottom++)
            {
                if (err + params->bias > 0)
                {
                    add_rect_to_region( region, &rect );
                    rect.top = rect.bottom;
                    rect.left += params->x_inc;
                    rect.right += params->x_inc;
                    err += params->err_add_1;
                }
                else err += params->err_add_2;
            }
        }
        else
        {
            for (len = params->length; len; len--, rect.top--)
            {
                if (err + params->bias > 0)
                {
                    add_rect_to_region( region, &rect );
                    rect.bottom = rect.top;
                    rect.left += params->x_inc;
                    rect.right += params->x_inc;
                    err += params->err_add_1;
                }
                else err += params->err_add_2;
            }
        }
    }
    /* add final rect */
    add_rect_to_region( region, &rect );
}

static BOOL solid_pen_line_region( dibdrv_physdev *pdev, POINT *start, POINT *end, HRGN region )
{
    RECT rect;

    rect.left   = start->x;
    rect.top    = start->y;
    rect.right  = start->x + 1;
    rect.bottom = start->y + 1;

    if (start->y == end->y)
    {
        rect.right = end->x;
        order_end_points(&rect.left, &rect.right);
        if (clip_rect_to_dib( &pdev->dib, &rect )) add_rect_to_region( region, &rect );
    }
    else if(start->x == end->x)
    {
        rect.bottom = end->y;
        order_end_points(&rect.top, &rect.bottom);
        if (clip_rect_to_dib( &pdev->dib, &rect )) add_rect_to_region( region, &rect );
    }
    else
    {
        bres_params clip_params;
        struct line_params line_params;
        POINT p1 = crop_coords( *start ), p2 = crop_coords( *end );

        init_bres_params( &p1, &p2, &clip_params, &line_params, &rect );
        if (clip_rect_to_dib( &pdev->dib, &rect ))
        {
            POINT clipped_start, clipped_end;

            if (clip_line( &p1, &p2, &rect, &clip_params, &clipped_start, &clipped_end ))
            {
                int m = abs(clipped_start.x - p1.x);
                int n = abs(clipped_start.y - p1.y);

                if (line_params.x_major)
                {
                    line_params.err_start = 2 * clip_params.dy - clip_params.dx
                                          + m * 2 * clip_params.dy - n * 2 * clip_params.dx;
                    line_params.length = abs( clipped_end.x - clipped_start.x ) + 1;
                }
                else
                {
                    line_params.err_start = 2 * clip_params.dx - clip_params.dy
                                          + n * 2 * clip_params.dx - m * 2 * clip_params.dy;
                    line_params.length = abs( clipped_end.y - clipped_start.y ) + 1;
                }

                if (clipped_end.x == p2.x && clipped_end.y == p2.y) line_params.length--;
                solid_line_region( &pdev->dib, &clipped_start, &line_params, region );
            }
        }
    }
    return TRUE;
}

static BOOL solid_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close, HRGN region)
{
    int i;

    assert( num >= 2 );

    if (region)
    {
        for (i = 0; i < num - 1; i++)
            if (!solid_pen_line_region( pdev, pts + i, pts + i + 1, region ))
                return FALSE;
        if (close) return solid_pen_line_region( pdev, pts + num - 1, pts, region );
    }
    else
    {
        DWORD color, and, xor;

        color = get_pixel_color( pdev, pdev->pen_brush.colorref, TRUE );
        calc_and_xor_masks( GetROP2(pdev->dev.hdc), color, &and, &xor );

        for (i = 0; i < num - 1; i++)
            if (!solid_pen_line( pdev, pts + i, pts + i + 1, and, xor ))
                return FALSE;
        if (close) return solid_pen_line( pdev, pts + num - 1, pts, and, xor );
    }
    return TRUE;
}

void reset_dash_origin(dibdrv_physdev *pdev)
{
    pdev->dash_pos.cur_dash = 0;
    pdev->dash_pos.left_in_dash = pdev->pen_pattern.dashes[0];
    pdev->dash_pos.mark = TRUE;
}

static inline void skip_dash(dibdrv_physdev *pdev, unsigned int skip)
{
    skip %= pdev->pen_pattern.total_len;
    do
    {
        if(pdev->dash_pos.left_in_dash > skip)
        {
            pdev->dash_pos.left_in_dash -= skip;
            return;
        }
        skip -= pdev->dash_pos.left_in_dash;
        pdev->dash_pos.cur_dash++;
        if(pdev->dash_pos.cur_dash == pdev->pen_pattern.count) pdev->dash_pos.cur_dash = 0;
        pdev->dash_pos.left_in_dash = pdev->pen_pattern.dashes[pdev->dash_pos.cur_dash];
        pdev->dash_pos.mark = !pdev->dash_pos.mark;
    }
    while (skip);
}

static void dashed_pen_line_callback(dibdrv_physdev *pdev, INT x, INT y)
{
    RECT rect;
    rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark];

    skip_dash(pdev, 1);
    rect.left   = x;
    rect.right  = x + 1;
    rect.top    = y;
    rect.bottom = y + 1;
    pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor);
    return;
}

static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end)
{
    struct clipped_rects clipped_rects;
    int i, dash_len;
    RECT rect;
    const dash_pos start_pos = pdev->dash_pos;

    if(start->y == end->y) /* hline */
    {
        BOOL l_to_r;
        INT left, right, cur_x;

        rect.top = start->y;
        rect.bottom = start->y + 1;

        if(start->x <= end->x)
        {
            left = start->x;
            right = end->x - 1;
            l_to_r = TRUE;
        }
        else
        {
            left = end->x + 1;
            right = start->x;
            l_to_r = FALSE;
        }

        rect.left = min( start->x, end->x );
        rect.right = max( start->x, end->x ) + 1;
        get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects );
        for (i = 0; i < clipped_rects.count; i++)
        {
            if(clipped_rects.rects[i].right > left && clipped_rects.rects[i].left <= right)
            {
                int clipped_left  = max(clipped_rects.rects[i].left, left);
                int clipped_right = min(clipped_rects.rects[i].right - 1, right);

                pdev->dash_pos = start_pos;

                if(l_to_r)
                {
                    cur_x = clipped_left;
                    if(cur_x != left)
                        skip_dash(pdev, clipped_left - left);

                    while(cur_x <= clipped_right)
                    {
                        rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark];
                        dash_len = pdev->dash_pos.left_in_dash;
                        if(cur_x + dash_len > clipped_right + 1)
                            dash_len = clipped_right - cur_x + 1;
                        rect.left = cur_x;
                        rect.right = cur_x + dash_len;

                        pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor);
                        cur_x += dash_len;
                        skip_dash(pdev, dash_len);
                    }
                }
                else
                {
                    cur_x = clipped_right;
                    if(cur_x != right)
                        skip_dash(pdev, right - clipped_right);

                    while(cur_x >= clipped_left)
                    {
                        rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark];
                        dash_len = pdev->dash_pos.left_in_dash;
                        if(cur_x - dash_len < clipped_left - 1)
                            dash_len = cur_x - clipped_left + 1;
                        rect.left = cur_x - dash_len + 1;
                        rect.right = cur_x + 1;

                        pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor);
                        cur_x -= dash_len;
                        skip_dash(pdev, dash_len);
                    }
                }
            }
        }
        pdev->dash_pos = start_pos;
        skip_dash(pdev, right - left + 1);
    }
    else if(start->x == end->x) /* vline */
    {
        BOOL t_to_b;
        INT top, bottom, cur_y;

        rect.left = start->x;
        rect.right = start->x + 1;

        if(start->y <= end->y)
        {
            top = start->y;
            bottom = end->y - 1;
            t_to_b = TRUE;
        }
        else
        {
            top = end->y + 1;
            bottom = start->y;
            t_to_b = FALSE;
        }

        rect.top = min( start->y, end->y );
        rect.bottom = max( start->y, end->y ) + 1;
        get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects );
        for (i = 0; i < clipped_rects.count; i++)
        {
            if(clipped_rects.rects[i].right > start->x && clipped_rects.rects[i].left <= start->x)
            {
                int clipped_top    = max(clipped_rects.rects[i].top, top);
                int clipped_bottom = min(clipped_rects.rects[i].bottom - 1, bottom);

                pdev->dash_pos = start_pos;

                if(t_to_b)
                {
                    cur_y = clipped_top;
                    if(cur_y != top)
                        skip_dash(pdev, clipped_top - top);

                    while(cur_y <= clipped_bottom)
                    {
                        rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark];
                        dash_len = pdev->dash_pos.left_in_dash;
                        if(cur_y + dash_len > clipped_bottom + 1)
                            dash_len = clipped_bottom - cur_y + 1;
                        rect.top = cur_y;
                        rect.bottom = cur_y + dash_len;

                        pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor);
                        cur_y += dash_len;
                        skip_dash(pdev, dash_len);
                    }
                }
                else
                {
                    cur_y = clipped_bottom;
                    if(cur_y != bottom)
                        skip_dash(pdev, bottom - clipped_bottom);

                    while(cur_y >= clipped_top)
                    {
                        rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark];
                        dash_len = pdev->dash_pos.left_in_dash;
                        if(cur_y - dash_len < clipped_top - 1)
                            dash_len = cur_y - clipped_top + 1;
                        rect.top = cur_y - dash_len + 1;
                        rect.bottom = cur_y + 1;

                        pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor);
                        cur_y -= dash_len;
                        skip_dash(pdev, dash_len);
                    }
                }
            }
        }
        pdev->dash_pos = start_pos;
        skip_dash(pdev, bottom - top + 1);
    }
    else
    {
        bres_params clip_params;
        struct line_params line_params;
        POINT p1 = crop_coords( *start ), p2 = crop_coords( *end );

        init_bres_params( &p1, &p2, &clip_params, &line_params, &rect );
        get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects );
        for (i = 0; i < clipped_rects.count; i++)
        {
            POINT clipped_start, clipped_end;
            int clip_status;
            clip_status = clip_line(&p1, &p2, clipped_rects.rects + i, &clip_params, &clipped_start, &clipped_end);

            if(clip_status)
            {
                int m = abs(clipped_start.x - p1.x);
                int n = abs(clipped_start.y - p1.y);

                pdev->dash_pos = start_pos;

                if (line_params.x_major)
                {
                    line_params.err_start = 2 * clip_params.dy - clip_params.dx
                                          + m * 2 * clip_params.dy - n * 2 * clip_params.dx;
                    line_params.length = abs( clipped_end.x - clipped_start.x ) + 1;
                    skip_dash(pdev, m);
                }
                else
                {
                    line_params.err_start = 2 * clip_params.dx - clip_params.dy
                                          + n * 2 * clip_params.dx - m * 2 * clip_params.dy;
                    line_params.length = abs( clipped_end.y - clipped_start.y ) + 1;
                    skip_dash(pdev, n);
                }
                if (clipped_end.x == end->x && clipped_end.y == end->y) line_params.length--;

                bres_line_with_bias( &clipped_start, &line_params, dashed_pen_line_callback, pdev );

                if(clip_status == 2) break; /* completely unclipped, so we can finish */
            }
        }
        pdev->dash_pos = start_pos;
        if(line_params.x_major)
            skip_dash(pdev, clip_params.dx);
        else
            skip_dash(pdev, clip_params.dy);
    }

    free_clipped_rects( &clipped_rects );
    return TRUE;
}

static BOOL dashed_pen_line_region(dibdrv_physdev *pdev, POINT *start, POINT *end, HRGN region)
{
    int i, dash_len;
    RECT rect;

    rect.left   = start->x;
    rect.top    = start->y;
    rect.right  = start->x + 1;
    rect.bottom = start->y + 1;

    if (start->y == end->y) /* hline */
    {
        if (start->x <= end->x)
        {
            for (i = start->x; i < end->x; i += dash_len)
            {
                dash_len = min( pdev->dash_pos.left_in_dash, end->x - i );
                if (pdev->dash_pos.mark)
                {
                    rect.left = i;
                    rect.right = i + dash_len;
                    add_rect_to_region( region, &rect );
                }
                skip_dash(pdev, dash_len);
            }
        }
        else
        {
            for (i = start->x; i > end->x; i -= dash_len)
            {
                dash_len = min( pdev->dash_pos.left_in_dash, i - end->x );
                if (pdev->dash_pos.mark)
                {
                    rect.left = i - dash_len + 1;
                    rect.right = i + 1;
                    add_rect_to_region( region, &rect );
                }
                skip_dash(pdev, dash_len);
            }
        }
    }
    else if (start->x == end->x) /* vline */
    {
        if (start->y <= end->y)
        {
            for (i = start->y; i < end->y; i += dash_len)
            {
                dash_len = min( pdev->dash_pos.left_in_dash, end->y - i );
                if (pdev->dash_pos.mark)
                {
                    rect.top = i;
                    rect.bottom = i + dash_len;
                    add_rect_to_region( region, &rect );
                }
                skip_dash(pdev, dash_len);
            }
        }
        else
        {
            for (i = start->y; i > end->y; i -= dash_len)
            {
                dash_len = min( pdev->dash_pos.left_in_dash, i - end->y );
                if (pdev->dash_pos.mark)
                {
                    rect.top = i - dash_len + 1;
                    rect.bottom = i + 1;
                    add_rect_to_region( region, &rect );
                }
                skip_dash(pdev, dash_len);
            }
        }
    }
    else
    {
        INT dx = end->x - start->x, dy = end->y - start->y;
        INT abs_dx = abs(dx), abs_dy = abs(dy);
        DWORD octant = get_octant_mask(dx, dy);
        INT bias = get_bias( octant );
        int x_inc = is_x_increasing( octant ) ? 1 : -1;
        int y_inc = is_y_increasing( octant ) ? 1 : -1;

        if (is_xmajor( octant ))
        {
            int err_add_1 = 2 * abs_dy - 2 * abs_dx;
            int err_add_2 = 2 * abs_dy;
            int err = 2 * abs_dy - abs_dx;

            while (abs_dx--)
            {
                if (pdev->dash_pos.mark) add_rect_to_region( region, &rect );
                skip_dash(pdev, 1);
                rect.left += x_inc;
                rect.right += x_inc;
                if (err + bias > 0)
                {
                    rect.top += y_inc;
                    rect.bottom += y_inc;
                    err += err_add_1;
                }
                else err += err_add_2;
            }

        }
        else
        {
            int err_add_1 = 2 * abs_dx - 2 * abs_dy;
            int err_add_2 = 2 * abs_dx;
            int err = 2 * abs_dx - abs_dy;

            while (abs_dy--)
            {
                if (pdev->dash_pos.mark) add_rect_to_region( region, &rect );
                skip_dash(pdev, 1);
                rect.top += y_inc;
                rect.bottom += y_inc;
                if (err + bias > 0)
                {
                    rect.left += x_inc;
                    rect.right += x_inc;
                    err += err_add_1;
                }
                else err += err_add_2;
            }
        }
    }
    return TRUE;
}

static BOOL dashed_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close, HRGN region)
{
    int i;

    assert( num >= 2 );

    if (region)
    {
        for (i = 0; i < num - 1; i++)
            if (!dashed_pen_line_region( pdev, pts + i, pts + i + 1, region ))
                return FALSE;
        if (close) return dashed_pen_line_region( pdev, pts + num - 1, pts, region );
    }
    else
    {
        get_color_masks( pdev, GetROP2(pdev->dev.hdc), pdev->pen_brush.colorref,
                         pdev->pen_is_ext ? TRANSPARENT : GetBkMode(pdev->dev.hdc),
                         &pdev->dash_masks[1], &pdev->dash_masks[0] );

        for (i = 0; i < num - 1; i++)
            if (!dashed_pen_line( pdev, pts + i, pts + i + 1 ))
                return FALSE;
        if (close) return dashed_pen_line( pdev, pts + num - 1, pts );
    }
    return TRUE;
}

static BOOL null_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close, HRGN region)
{
    return TRUE;
}

struct face
{
    POINT start, end;
    int dx, dy;
};

static void add_cap( dibdrv_physdev *pdev, HRGN region, HRGN round_cap, const POINT *pt )
{
    switch (pdev->pen_endcap)
    {
    default: FIXME( "Unknown end cap %x\n", pdev->pen_endcap );
        /* fall through */
    case PS_ENDCAP_ROUND:
        OffsetRgn( round_cap, pt->x, pt->y );
        CombineRgn( region, region, round_cap, RGN_OR );
        OffsetRgn( round_cap, -pt->x, -pt->y );
        return;

    case PS_ENDCAP_SQUARE: /* already been handled */
    case PS_ENDCAP_FLAT:
        return;
    }
}

#define round( f ) (((f) > 0) ? (f) + 0.5 : (f) - 0.5)

/*******************************************************************************
 *                 create_miter_region
 *
 * We need to calculate the intersection of two lines.  We know a point
 * on each line (a face start and the other face end point) and
 * the direction vector of each line eg. (dx_1, dy_1).
 *
 * (x, y) = (x_1, y_1) + u * (dx_1, dy_1) = (x_2, y_2) + v * (dx_2, dy_2)
 * solving (eg using Cramer's rule) gives:
 * u = ((x_2 - x_1) dy_2 - (y_2 - y_1) dx_2) / det
 * with det = dx_1 dy_2 - dx_2 dy_1
 * substituting back in and simplifying gives
 * (x, y) = a (dx_1, dy_1) - b (dx_2, dy_2)
 * with a = (x_2 dy_2 - y_2 dx_2) / det
 * and  b = (x_1 dy_1 - y_1 dx_1) / det
 */
static HRGN create_miter_region( dibdrv_physdev *pdev, const POINT *pt,
                                 const struct face *face_1, const struct face *face_2 )
{
    int det = face_1->dx * face_2->dy - face_1->dy * face_2->dx;
    POINT pt_1, pt_2, pts[5];
    double a, b, x, y;
    FLOAT limit;

    if (det == 0) return 0;

    if (det < 0)
    {
        const struct face *tmp = face_1;
        face_1 = face_2;
        face_2 = tmp;
        det = -det;
    }

    pt_1 = face_1->start;
    pt_2 = face_2->end;

    a = (double)((pt_2.x * face_2->dy - pt_2.y * face_2->dx)) / det;
    b = (double)((pt_1.x * face_1->dy - pt_1.y * face_1->dx)) / det;

    x = a * face_1->dx - b * face_2->dx;
    y = a * face_1->dy - b * face_2->dy;

    GetMiterLimit( pdev->dev.hdc, &limit );

    if (((x - pt->x) * (x - pt->x) + (y - pt->y) * (y - pt->y)) * 4 > limit * limit * pdev->pen_width * pdev->pen_width)
        return 0;

    pts[0] = face_2->start;
    pts[1] = face_1->start;
    pts[2].x = round( x );
    pts[2].y = round( y );
    pts[3] = face_2->end;
    pts[4] = face_1->end;

    return CreatePolygonRgn( pts, 5, ALTERNATE );
}

static void add_join( dibdrv_physdev *pdev, HRGN region, HRGN round_cap, const POINT *pt,
                      const struct face *face_1, const struct face *face_2 )
{
    HRGN join;
    POINT pts[4];

    switch (pdev->pen_join)
    {
    default: FIXME( "Unknown line join %x\n", pdev->pen_join );
        /* fall through */
    case PS_JOIN_ROUND:
        OffsetRgn( round_cap, pt->x, pt->y );
        CombineRgn( region, region, round_cap, RGN_OR );
        OffsetRgn( round_cap, -pt->x, -pt->y );
        return;

    case PS_JOIN_MITER:
        join = create_miter_region( pdev, pt, face_1, face_2 );
        if (join) break;
        /* fall through */
    case PS_JOIN_BEVEL:
        pts[0] = face_1->start;
        pts[1] = face_2->end;
        pts[2] = face_1->end;
        pts[3] = face_2->start;
        join = CreatePolygonRgn( pts, 4, ALTERNATE );
        break;
    }

    CombineRgn( region, region, join, RGN_OR );
    DeleteObject( join );
    return;
}

static int wide_line_segment( dibdrv_physdev *pdev, HRGN total,
                               const POINT *pt_1, const POINT *pt_2, int dx, int dy,
                               BOOL need_cap_1, BOOL need_cap_2, struct face *face_1, struct face *face_2 )
{
    RECT rect;
    BOOL sq_cap_1 = need_cap_1 && (pdev->pen_endcap == PS_ENDCAP_SQUARE);
    BOOL sq_cap_2 = need_cap_2 && (pdev->pen_endcap == PS_ENDCAP_SQUARE);

    if (dx == 0 && dy == 0) return 0;

    if (dy == 0)
    {
        rect.left = min( pt_1->x, pt_2->x );
        rect.right = max( pt_1->x, pt_2->x );
        rect.top = pt_1->y - pdev->pen_width / 2;
        rect.bottom = rect.top + pdev->pen_width;
        if ((sq_cap_1 && dx > 0) || (sq_cap_2 && dx < 0)) rect.left  -= pdev->pen_width / 2;
        if ((sq_cap_2 && dx > 0) || (sq_cap_1 && dx < 0)) rect.right += pdev->pen_width / 2;
        add_rect_to_region( total, &rect );
        if (dx > 0)
        {
            face_1->start.x = face_1->end.x   = rect.left;
            face_1->start.y = face_2->end.y   = rect.bottom;
            face_1->end.y   = face_2->start.y = rect.top;
            face_2->start.x = face_2->end.x   = rect.right - 1;
        }
        else
        {
            face_1->start.x = face_1->end.x   = rect.right;
            face_1->start.y = face_2->end.y   = rect.top;
            face_1->end.y   = face_2->start.y = rect.bottom;
            face_2->start.x = face_2->end.x   = rect.left + 1;
        }
    }
    else if (dx == 0)
    {
        rect.top = min( pt_1->y, pt_2->y );
        rect.bottom = max( pt_1->y, pt_2->y );
        rect.left = pt_1->x - pdev->pen_width / 2;
        rect.right = rect.left + pdev->pen_width;
        if ((sq_cap_1 && dy > 0) || (sq_cap_2 && dy < 0)) rect.top    -= pdev->pen_width / 2;
        if ((sq_cap_2 && dy > 0) || (sq_cap_1 && dy < 0)) rect.bottom += pdev->pen_width / 2;
        add_rect_to_region( total, &rect );
        if (dy > 0)
        {
            face_1->start.x = face_2->end.x   = rect.left;
            face_1->start.y = face_1->end.y   = rect.top;
            face_1->end.x   = face_2->start.x = rect.right;
            face_2->start.y = face_2->end.y   = rect.bottom - 1;
        }
        else
        {
            face_1->start.x = face_2->end.x   = rect.right;
            face_1->start.y = face_1->end.y   = rect.bottom;
            face_1->end.x   = face_2->start.x = rect.left;
            face_2->start.y = face_2->end.y   = rect.top + 1;
        }
    }
    else
    {
        double len = hypot( dx, dy );
        double width_x, width_y;
        POINT seg_pts[4];
        POINT wide_half, narrow_half;
        HRGN segment;

        width_x = pdev->pen_width * abs( dy ) / len;
        width_y = pdev->pen_width * abs( dx ) / len;

        narrow_half.x = round( width_x / 2 );
        narrow_half.y = round( width_y / 2 );
        wide_half.x   = round( (width_x + 1) / 2 );
        wide_half.y   = round( (width_y + 1) / 2 );

        if (dx < 0)
        {
            wide_half.y   = -wide_half.y;
            narrow_half.y = -narrow_half.y;
        }

        if (dy < 0)
        {
            POINT tmp = narrow_half; narrow_half = wide_half; wide_half = tmp;
            wide_half.x   = -wide_half.x;
            narrow_half.x = -narrow_half.x;
        }

        seg_pts[0].x = pt_1->x - narrow_half.x;
        seg_pts[0].y = pt_1->y + narrow_half.y;
        seg_pts[1].x = pt_1->x + wide_half.x;
        seg_pts[1].y = pt_1->y - wide_half.y;
        seg_pts[2].x = pt_2->x + wide_half.x;
        seg_pts[2].y = pt_2->y - wide_half.y;
        seg_pts[3].x = pt_2->x - narrow_half.x;
        seg_pts[3].y = pt_2->y + narrow_half.y;

        if (sq_cap_1)
        {
            seg_pts[0].x -= narrow_half.y;
            seg_pts[1].x -= narrow_half.y;
            seg_pts[0].y -= narrow_half.x;
            seg_pts[1].y -= narrow_half.x;
        }

        if (sq_cap_2)
        {
            seg_pts[2].x += wide_half.y;
            seg_pts[3].x += wide_half.y;
            seg_pts[2].y += wide_half.x;
            seg_pts[3].y += wide_half.x;
        }

        segment = CreatePolygonRgn( seg_pts, 4, ALTERNATE );
        CombineRgn( total, total, segment, RGN_OR );
        DeleteObject( segment );

        face_1->start = seg_pts[0];
        face_1->end   = seg_pts[1];
        face_2->start = seg_pts[2];
        face_2->end   = seg_pts[3];
    }

    face_1->dx = face_2->dx = dx;
    face_1->dy = face_2->dy = dy;

    return 1;
}

static void wide_line_segments( dibdrv_physdev *pdev, int num, const POINT *pts, BOOL close,
                                int start, int count, const POINT *first_pt, const POINT *last_pt,
                                HRGN round_cap, HRGN total )
{
    int i;
    struct face face_1, face_2, prev_face, first_face;
    const POINT *pt_1, *pt_2;

    if (!close)
    {
        add_cap( pdev, total, round_cap, first_pt );
        add_cap( pdev, total, round_cap, last_pt );
    }

    if (count == 1)
    {
        pt_1 = &pts[start];
        pt_2 = &pts[(start + 1) % num];
        wide_line_segment( pdev, total, first_pt, last_pt, pt_2->x - pt_1->x, pt_2->y - pt_1->y,
                           TRUE, TRUE, &face_1, &face_2 );
        return;
    }

    pt_1 = &pts[start];
    pt_2 = &pts[(start + 1) % num];
    wide_line_segment( pdev, total, first_pt, pt_2, pt_2->x - pt_1->x, pt_2->y - pt_1->y,
                       !close, FALSE, &first_face, &prev_face );


    for (i = 1; i < count - 1; i++)
    {
        pt_1 = &pts[(start + i) % num];
        pt_2 = &pts[(start + i + 1) % num];
        if (wide_line_segment( pdev, total, pt_1, pt_2, pt_2->x - pt_1->x, pt_2->y - pt_1->y,
                               FALSE, FALSE, &face_1, &face_2 ))
        {
            add_join( pdev, total, round_cap, pt_1, &prev_face, &face_1 );
            prev_face = face_2;
        }
    }

    pt_1 = &pts[(start + count - 1) % num];
    pt_2 = &pts[(start + count) % num];
    wide_line_segment( pdev, total, pt_1, last_pt, pt_2->x - pt_1->x, pt_2->y - pt_1->y,
                       FALSE, !close, &face_1, &face_2 );
    add_join( pdev, total, round_cap, pt_1, &prev_face, &face_1 );
    if (close) add_join( pdev, total, round_cap, last_pt, &face_2, &first_face );
}

static BOOL wide_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close, HRGN total)
{
    HRGN round_cap = 0;

    assert( total != 0 );  /* wide pens should always be drawn through a region */
    assert( num >= 2 );

    /* skip empty segments */
    while (num > 2 && pts[0].x == pts[1].x && pts[0].y == pts[1].y) { pts++; num--; }
    while (num > 2 && pts[num - 1].x == pts[num - 2].x && pts[num - 1].y == pts[num - 2].y) num--;

    if (pdev->pen_join == PS_JOIN_ROUND || pdev->pen_endcap == PS_ENDCAP_ROUND)
        round_cap = CreateEllipticRgn( -(pdev->pen_width / 2), -(pdev->pen_width / 2),
                                       (pdev->pen_width + 1) / 2 + 1, (pdev->pen_width + 1) / 2 + 1 );

    if (close)
        wide_line_segments( pdev, num, pts, TRUE, 0, num, &pts[0], &pts[0], round_cap, total );
    else
        wide_line_segments( pdev, num, pts, FALSE, 0, num - 1, &pts[0], &pts[num - 1], round_cap, total );

    if (round_cap) DeleteObject( round_cap );
    return TRUE;
}

static BOOL dashed_wide_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close, HRGN total)
{
    int i, start, cur_len, initial_num = 0;
    POINT initial_point, start_point, end_point;
    HRGN round_cap = 0;

    assert( total != 0 );  /* wide pens should always be drawn through a region */
    assert( num >= 2 );

    /* skip empty segments */
    while (num > 2 && pts[0].x == pts[1].x && pts[0].y == pts[1].y) { pts++; num--; }
    while (num > 2 && pts[num - 1].x == pts[num - 2].x && pts[num - 1].y == pts[num - 2].y) num--;

    if (pdev->pen_join == PS_JOIN_ROUND || pdev->pen_endcap == PS_ENDCAP_ROUND)
        round_cap = CreateEllipticRgn( -(pdev->pen_width / 2), -(pdev->pen_width / 2),
                                       (pdev->pen_width + 1) / 2 + 1, (pdev->pen_width + 1) / 2 + 1);

    start = 0;
    cur_len = 0;
    start_point = pts[0];

    for (i = 0; i < (close ? num : num - 1); i++)
    {
        const POINT *pt_1 = pts + i;
        const POINT *pt_2 = pts + ((close && i == num - 1) ? 0 : i + 1);
        int dx = pt_2->x - pt_1->x;
        int dy = pt_2->y - pt_1->y;

        if (dx == 0 && dy == 0) continue;

        if (dy == 0)
        {
            if (abs( dx ) - cur_len < pdev->dash_pos.left_in_dash)
            {
                skip_dash( pdev, abs( dx ) - cur_len );
                cur_len = 0;
                continue;
            }
            cur_len += pdev->dash_pos.left_in_dash;
            dx = (dx > 0) ? cur_len : -cur_len;
        }
        else if (dx == 0)
        {
            if (abs( dy ) - cur_len < pdev->dash_pos.left_in_dash)
            {
                skip_dash( pdev, abs( dy ) - cur_len );
                cur_len = 0;
                continue;
            }
            cur_len += pdev->dash_pos.left_in_dash;
            dy = (dy > 0) ? cur_len : -cur_len;
        }
        else
        {
            double len = hypot( dx, dy );

            if (len - cur_len < pdev->dash_pos.left_in_dash)
            {
                skip_dash( pdev, len - cur_len );
                cur_len = 0;
                continue;
            }
            cur_len += pdev->dash_pos.left_in_dash;
            dx = dx * cur_len / len;
            dy = dy * cur_len / len;
        }
        end_point.x = pt_1->x + dx;
        end_point.y = pt_1->y + dy;

        if (pdev->dash_pos.mark)
        {
            if (!initial_num && close)  /* this is the first dash, save it for later */
            {
                initial_num = i - start + 1;
                initial_point = end_point;
            }
            else wide_line_segments( pdev, num, pts, FALSE, start, i - start + 1,
                                     &start_point, &end_point, round_cap, total );
        }
        if (!initial_num) initial_num = -1;  /* no need to close it */

        skip_dash( pdev, pdev->dash_pos.left_in_dash );
        start_point = end_point;
        start = i;
        i--;  /* go on with the same segment */
    }

    if (pdev->dash_pos.mark)  /* we have a final dash */
    {
        int count;

        if (initial_num > 0)
        {
            count = num - start + initial_num;
            end_point = initial_point;
        }
        else if (close)
        {
            count = num - start;
            end_point = pts[0];
        }
        else
        {
            count = num - start - 1;
            end_point = pts[num - 1];
        }
        wide_line_segments( pdev, num, pts, FALSE, start, count,
                            &start_point, &end_point, round_cap, total );
    }
    else if (initial_num > 0)  /* initial dash only */
    {
        wide_line_segments( pdev, num, pts, FALSE, 0, initial_num,
                            &pts[0], &initial_point, round_cap, total );
    }

    if (round_cap) DeleteObject( round_cap );
    return TRUE;
}

static const dash_pattern dash_patterns_cosmetic[4] =
{
    {2, {18, 6}, 24},             /* PS_DASH */
    {2, {3,  3}, 6},              /* PS_DOT */
    {4, {9, 6, 3, 6}, 24},        /* PS_DASHDOT */
    {6, {9, 3, 3, 3, 3, 3}, 24}   /* PS_DASHDOTDOT */
};

static const dash_pattern dash_patterns_geometric[4] =
{
    {2, {3, 1}, 4},               /* PS_DASH */
    {2, {1, 1}, 2},               /* PS_DOT */
    {4, {3, 1, 1, 1}, 6},         /* PS_DASHDOT */
    {6, {3, 1, 1, 1, 1, 1}, 8}    /* PS_DASHDOTDOT */
};

static inline void set_dash_pattern( dash_pattern *pattern, DWORD count, DWORD *dashes )
{
    DWORD i;

    pattern->count = count;
    pattern->total_len = 0;
    memcpy( pattern->dashes, dashes, count * sizeof(DWORD) );
    for (i = 0; i < count; i++) pattern->total_len += dashes[i];
    if (pattern->count % 2) pattern->total_len *= 2;
}

static inline void scale_dash_pattern( dash_pattern *pattern, DWORD scale, DWORD endcap )
{
    DWORD i;

    for (i = 0; i < pattern->count; i++) pattern->dashes[i] *= scale;
    pattern->total_len *= scale;

    if (endcap != PS_ENDCAP_FLAT)  /* shrink the dashes to leave room for the caps */
    {
        for (i = 0; i < pattern->count; i += 2)
        {
            pattern->dashes[i] -= scale;
            pattern->dashes[i + 1] += scale;
        }
    }
}

static inline int get_pen_device_width( dibdrv_physdev *pdev, int width )
{
    POINT pts[2];

    if (!width) return 1;
    pts[0].x = pts[0].y = pts[1].y = 0;
    pts[1].x = width;
    LPtoDP( pdev->dev.hdc, pts, 2 );
    width = abs( pts[1].x - pts[0].x );
    return max( width, 1 );
}

/***********************************************************************
 *           dibdrv_SetDCPenColor
 */
COLORREF dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color )
{
    dibdrv_physdev *pdev = get_dibdrv_pdev(dev);

    if (GetCurrentObject(dev->hdc, OBJ_PEN) == GetStockObject( DC_PEN ))
        pdev->pen_brush.colorref = color;

    return color;
}

/**********************************************************************
 *             solid_brush
 *
 * Fill a number of rectangles with the solid brush
 */
static BOOL solid_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
                        int num, const RECT *rects, INT rop)
{
    rop_mask brush_color;
    DWORD color = get_pixel_color( pdev, brush->colorref, TRUE );

    calc_rop_masks( rop, color, &brush_color );
    dib->funcs->solid_rects( dib, num, rects, brush_color.and, brush_color.xor );
    return TRUE;
}

static BOOL alloc_brush_mask_bits( dib_brush *brush )
{
    DWORD size = brush->dib.height * abs(brush->dib.stride);

    assert(brush->masks.and == NULL);
    assert(brush->masks.xor == NULL);
    assert(brush->dib.stride > 0);

    if (!(brush->masks.and = HeapAlloc(GetProcessHeap(), 0, 2 * size))) return FALSE;
    brush->masks.xor = (char *)brush->masks.and + size;
    return TRUE;
}

static void free_brush_mask_bits( dib_brush *brush )
{
    HeapFree(GetProcessHeap(), 0, brush->masks.and);
    brush->masks.and = brush->masks.xor = NULL;
}

void free_pattern_brush( dib_brush *brush )
{
    free_brush_mask_bits( brush );
    free_dib_info( &brush->dib );
}

static BOOL create_pattern_brush_bits( dib_brush *brush )
{
    DWORD size = brush->dib.height * abs(brush->dib.stride);
    DWORD *brush_bits = brush->dib.bits.ptr;
    DWORD *and_bits, *xor_bits;

    if (!alloc_brush_mask_bits( brush )) return FALSE;

    and_bits = brush->masks.and;
    xor_bits = brush->masks.xor;

    while(size)
    {
        calc_and_xor_masks(brush->rop, *brush_bits++, and_bits++, xor_bits++);
        size -= 4;
    }

    return TRUE;
}

static const BYTE hatches[6][8] =
{
    { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HS_HORIZONTAL */
    { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HS_VERTICAL   */
    { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HS_FDIAGONAL  */
    { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HS_BDIAGONAL  */
    { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HS_CROSS      */
    { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }  /* HS_DIAGCROSS  */
};

static BOOL init_hatch_brush( dibdrv_physdev *pdev, dib_brush *brush )
{
    /* Just initialise brush dib with the color / sizing info.  We don't
       need the bits as we'll calculate the rop masks straight from
       the hatch patterns. */

    copy_dib_color_info(&brush->dib, &pdev->dib);
    brush->dib.width  = 8;
    brush->dib.height = 8;
    brush->dib.stride = get_dib_stride( brush->dib.width, brush->dib.bit_count );
    brush->dib.rect.left   = 0;
    brush->dib.rect.top    = 0;
    brush->dib.rect.right  = 8;
    brush->dib.rect.bottom = 8;
    return alloc_brush_mask_bits( brush );
}

static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev, dib_brush *brush, BOOL *needs_reselect)
{
    rop_mask fg_mask, bg_mask;

    if (!init_hatch_brush( pdev, brush )) return FALSE;

    get_color_masks( pdev, brush->rop, brush->colorref, GetBkMode(pdev->dev.hdc),
                     &fg_mask, &bg_mask );

    if (brush->colorref & (1 << 24))  /* PALETTEINDEX */
        *needs_reselect = TRUE;
    if (GetBkMode(pdev->dev.hdc) != TRANSPARENT && (GetBkColor(pdev->dev.hdc) & (1 << 24)))
        *needs_reselect = TRUE;

    brush->dib.funcs->create_rop_masks( &brush->dib, hatches[brush->hatch],
                                        &fg_mask, &bg_mask, &brush->masks );
    return TRUE;
}

static BOOL create_dither_brush_bits(dibdrv_physdev *pdev, dib_brush *brush, BOOL *needs_reselect)
{
    COLORREF rgb;
    DWORD pixel;
    BOOL got_pixel;

    if (!init_hatch_brush( pdev, brush )) return FALSE;

    if (brush->colorref & (1 << 24))  /* PALETTEINDEX */
        *needs_reselect = TRUE;

    rgb = make_rgb_colorref( pdev->dev.hdc, &pdev->dib, brush->colorref, &got_pixel, &pixel );

    brush->dib.funcs->create_dither_masks( &brush->dib, brush->rop, rgb, &brush->masks );
    return TRUE;
}

static BOOL matching_pattern_format( dib_info *dib, dib_info *pattern )
{
    if (dib->bit_count != pattern->bit_count) return FALSE;
    if (dib->stride != pattern->stride) return FALSE;

    switch (dib->bit_count)
    {
    case 1:
    case 4:
    case 8:
        if (dib->color_table_size != pattern->color_table_size) return FALSE;
        return !memcmp( dib->color_table, pattern->color_table, dib->color_table_size * sizeof(RGBQUAD) );
    case 16:
    case 32:
        return (dib->red_mask == pattern->red_mask &&
                dib->green_mask == pattern->green_mask &&
                dib->blue_mask == pattern->blue_mask);
    }
    return TRUE;
}

static BOOL select_pattern_brush( dibdrv_physdev *pdev, dib_brush *brush, BOOL *needs_reselect )
{
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *info = (BITMAPINFO *)buffer;
    RGBQUAD color_table[2];
    dib_info pattern;
    BOOL dither = (brush->dib.bit_count == 1);

    if (brush->pattern.info->bmiHeader.biClrUsed && brush->pattern.usage == DIB_PAL_COLORS)
    {
        copy_bitmapinfo( info, brush->pattern.info );
        fill_color_table_from_pal_colors( info, pdev->dev.hdc );
        init_dib_info_from_bitmapinfo( &pattern, info, brush->pattern.bits.ptr );
        *needs_reselect = TRUE;
    }
    else
    {
        init_dib_info_from_bitmapinfo( &pattern, brush->pattern.info, brush->pattern.bits.ptr );
    }

    if (pattern.bit_count == 1 && !pattern.color_table)
        dither = FALSE;  /* monochrome DDB pattern brushes don't get dithered */

    if (pattern.bit_count == 1 && !pattern.color_table &&
        (pdev->dib.bit_count != 1 || pdev->dib.color_table))
    {
        /* monochrome DDB pattern uses DC colors */
        DWORD pixel;
        BOOL got_pixel;
        COLORREF color;

        color = make_rgb_colorref( pdev->dev.hdc, &pdev->dib, GetTextColor( pdev->dev.hdc ),
                                   &got_pixel, &pixel );
        color_table[0].rgbRed      = GetRValue( color );
        color_table[0].rgbGreen    = GetGValue( color );
        color_table[0].rgbBlue     = GetBValue( color );
        color_table[0].rgbReserved = 0;

        color = make_rgb_colorref( pdev->dev.hdc, &pdev->dib, GetBkColor( pdev->dev.hdc ),
                                   &got_pixel, &pixel );
        color_table[1].rgbRed      = GetRValue( color );
        color_table[1].rgbGreen    = GetGValue( color );
        color_table[1].rgbBlue     = GetBValue( color );
        color_table[1].rgbReserved = 0;

        pattern.color_table = color_table;
        pattern.color_table_size = 2;
        *needs_reselect = TRUE;
    }

    copy_dib_color_info(&brush->dib, &pdev->dib);

    brush->dib.height = pattern.height;
    brush->dib.width  = pattern.width;
    brush->dib.stride = get_dib_stride( brush->dib.width, brush->dib.bit_count );
    brush->dib.rect   = pattern.rect;

    if (!dither && matching_pattern_format( &brush->dib, &pattern ))
    {
        brush->dib.bits.ptr     = pattern.bits.ptr;
        brush->dib.bits.is_copy = FALSE;
        brush->dib.bits.free    = NULL;
    }
    else
    {
        brush->dib.bits.ptr     = HeapAlloc( GetProcessHeap(), 0, brush->dib.height * brush->dib.stride );
        brush->dib.bits.is_copy = TRUE;
        brush->dib.bits.free    = free_heap_bits;
        brush->dib.funcs->convert_to(&brush->dib, &pattern, &pattern.rect, dither);
    }
    return TRUE;
}

/**********************************************************************
 *             pattern_brush
 *
 * Fill a number of rectangles with the pattern brush
 * FIXME: Should we insist l < r && t < b?  Currently we assume this.
 */
static BOOL pattern_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
                          int num, const RECT *rects, INT rop)
{
    POINT origin;
    BOOL needs_reselect = FALSE;

    if (rop != brush->rop)
    {
        free_brush_mask_bits( brush );
        brush->rop = rop;
    }

    if(brush->masks.and == NULL)
    {
        switch(brush->style)
        {
        case BS_DIBPATTERN:
            if (!brush->dib.bits.ptr && !select_pattern_brush( pdev, brush, &needs_reselect ))
                return FALSE;
            if(!create_pattern_brush_bits( brush ))
                return FALSE;
            break;

        case BS_SOLID:
            if(!create_dither_brush_bits(pdev, brush, &needs_reselect))
                return FALSE;
            break;

        case BS_HATCHED:
            if(!create_hatch_brush_bits(pdev, brush, &needs_reselect))
                return FALSE;
            break;

        default:
            ERR("Unexpected brush style %d\n", brush->style);
            return FALSE;
        }
    }

    GetBrushOrgEx(pdev->dev.hdc, &origin);

    dib->funcs->pattern_rects( dib, num, rects, &origin, &brush->dib, &brush->masks );

    if (needs_reselect) free_pattern_brush( brush );
    return TRUE;
}

static BOOL null_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
                       int num, const RECT *rects, INT rop)
{
    return TRUE;
}

static BOOL brush_needs_dithering( dibdrv_physdev *pdev, COLORREF color )
{
    int i;
    RGBQUAD rgb;
    const RGBQUAD *color_table = get_default_color_table( pdev->dib.bit_count );

    if (!color_table) return FALSE;
    if (pdev->dib.color_table) return FALSE;
    if (color & (1 << 24)) return TRUE;  /* PALETTEINDEX */
    if (color >> 16 == 0x10ff) return FALSE;  /* DIBINDEX */

    rgb = rgbquad_from_colorref( color );
    for (i = 0; i < (1 << pdev->dib.bit_count); i++)
        if (rgbquad_equal( &color_table[i], &rgb )) return FALSE;

    return TRUE;
}

static void select_brush( dibdrv_physdev *pdev, dib_brush *brush,
                          const LOGBRUSH *logbrush, const struct brush_pattern *pattern )
{
    free_pattern_brush( brush );

    if (pattern)
    {
        brush->style   = BS_DIBPATTERN;
        brush->pattern = *pattern;  /* brush is actually selected only when it's used */
        brush->rects   = pattern_brush;
    }
    else
    {
        brush->style    = logbrush->lbStyle;
        brush->colorref = logbrush->lbColor;
        brush->hatch    = logbrush->lbHatch;

        switch (logbrush->lbStyle)
        {
        case BS_NULL:    brush->rects = null_brush; break;
        case BS_HATCHED: brush->rects = pattern_brush; break;
        case BS_SOLID:
            brush->rects = brush_needs_dithering( pdev, brush->colorref ) ? pattern_brush : solid_brush;
            break;
        }
    }
}

/***********************************************************************
 *           dibdrv_SelectBrush
 */
HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, const struct brush_pattern *pattern )
{
    dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
    LOGBRUSH logbrush;

    TRACE("(%p, %p)\n", dev, hbrush);

    GetObjectW( hbrush, sizeof(logbrush), &logbrush );

    if (hbrush == GetStockObject( DC_BRUSH ))
        logbrush.lbColor = GetDCBrushColor( dev->hdc );

    select_brush( pdev, &pdev->brush, &logbrush, pattern );
    return hbrush;
}

/***********************************************************************
 *           dibdrv_SelectPen
 */
HPEN dibdrv_SelectPen( PHYSDEV dev, HPEN hpen, const struct brush_pattern *pattern )
{
    dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
    LOGPEN logpen;
    LOGBRUSH logbrush;
    EXTLOGPEN *elp = NULL;

    TRACE("(%p, %p)\n", dev, hpen);

    if (!GetObjectW( hpen, sizeof(logpen), &logpen ))
    {
        /* must be an extended pen */
        INT size = GetObjectW( hpen, 0, NULL );

        if (!size) return 0;

        elp = HeapAlloc( GetProcessHeap(), 0, size );

        GetObjectW( hpen, size, elp );
        logpen.lopnStyle = elp->elpPenStyle;
        logpen.lopnWidth.x = elp->elpWidth;
        /* cosmetic ext pens are always 1-pixel wide */
        if (!(logpen.lopnStyle & PS_GEOMETRIC)) logpen.lopnWidth.x = 0;

        logbrush.lbStyle = elp->elpBrushStyle;
        logbrush.lbColor = elp->elpColor;
        logbrush.lbHatch = elp->elpHatch;
    }
    else
    {
        logbrush.lbStyle = BS_SOLID;
        logbrush.lbColor = logpen.lopnColor;
        logbrush.lbHatch = 0;
    }

    pdev->pen_join   = logpen.lopnStyle & PS_JOIN_MASK;
    pdev->pen_endcap = logpen.lopnStyle & PS_ENDCAP_MASK;
    pdev->pen_width  = get_pen_device_width( pdev, logpen.lopnWidth.x );

    if (hpen == GetStockObject( DC_PEN ))
        logbrush.lbColor = GetDCPenColor( dev->hdc );

    set_dash_pattern( &pdev->pen_pattern, 0, NULL );
    select_brush( pdev, &pdev->pen_brush, &logbrush, pattern );

    pdev->pen_style = logpen.lopnStyle & PS_STYLE_MASK;

    switch (pdev->pen_style)
    {
    case PS_DASH:
    case PS_DOT:
    case PS_DASHDOT:
    case PS_DASHDOTDOT:
        if (logpen.lopnStyle & PS_GEOMETRIC)
        {
            pdev->pen_pattern = dash_patterns_geometric[pdev->pen_style - 1];
            if (pdev->pen_width > 1)
            {
                scale_dash_pattern( &pdev->pen_pattern, pdev->pen_width, pdev->pen_endcap );
                pdev->pen_lines = dashed_wide_pen_lines;
            }
            else pdev->pen_lines = dashed_pen_lines;
            break;
        }
        if (pdev->pen_width == 1)  /* wide cosmetic pens are not dashed */
        {
            pdev->pen_lines = dashed_pen_lines;
            pdev->pen_pattern = dash_patterns_cosmetic[pdev->pen_style - 1];
            break;
        }
        /* fall through */
    case PS_SOLID:
    case PS_INSIDEFRAME:
        pdev->pen_lines = (pdev->pen_width == 1) ? solid_pen_lines : wide_pen_lines;
        break;

    case PS_NULL:
        pdev->pen_width = 0;
        pdev->pen_lines = null_pen_lines;
        break;

    case PS_ALTERNATE:
        pdev->pen_lines = dashed_pen_lines;
        pdev->pen_pattern = dash_patterns_geometric[PS_DOT - 1];
        break;

    case PS_USERSTYLE:
        pdev->pen_lines = (pdev->pen_width == 1) ? dashed_pen_lines : dashed_wide_pen_lines;
        set_dash_pattern( &pdev->pen_pattern, elp->elpNumEntries, elp->elpStyleEntry );
        if (!(logpen.lopnStyle & PS_GEOMETRIC)) scale_dash_pattern( &pdev->pen_pattern, 3, PS_ENDCAP_FLAT );
        break;
    }

    pdev->pen_uses_region = (logpen.lopnStyle & PS_GEOMETRIC || pdev->pen_width > 1);
    pdev->pen_is_ext = (elp != NULL);
    HeapFree( GetProcessHeap(), 0, elp );
    return hpen;
}

/***********************************************************************
 *           dibdrv_SetDCBrushColor
 */
COLORREF dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF color )
{
    dibdrv_physdev *pdev = get_dibdrv_pdev(dev);

    if (GetCurrentObject(dev->hdc, OBJ_BRUSH) == GetStockObject( DC_BRUSH ))
    {
        LOGBRUSH logbrush = { BS_SOLID, color, 0 };
        select_brush( pdev, &pdev->brush, &logbrush, NULL );
    }
    return color;
}
