Changeset 681


Ignore:
Timestamp:
May 19, 2011, 1:45:51 AM (8 years ago)
Author:
Sam Hocevar
Message:

imlib: simplify the line drawing method.

Location:
abuse/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • abuse/trunk/TODO

    r679 r681  
    7070button::area
    7171
    72 refactor image::Line to merge loops
    73 
  • abuse/trunk/src/imlib/image.cpp

    r680 r681  
    181181void image::Line(vec2i p1, vec2i p2, uint8_t color)
    182182{
    183     int xc, yc, er, n, m, xi, yi, xcxi, ycyi, xcyi;
    184     unsigned int dcy, dcx;
    185 
    186183    // check to see if the line is completly clipped off
    187184    vec2i caa, cbb;
    188185    GetClip(caa, cbb);
    189186
    190     if ((p1.x < caa.x && p2.x < caa.x) || (p1.x >= cbb.x && p2.x >= cbb.x) ||
    191         (p1.y < caa.y && p2.y < caa.y) || (p1.y >= cbb.y && p2.y >= cbb.y))
    192         return;
    193 
    194187    if (p1.x > p2.x) // make sure that p1.x is to the left
    195188    {
     
    197190    }
    198191
    199     // clip the left side
     192    // clip the left and right sides
     193    if ((p1.x < caa.x && p2.x < caa.x) || (p1.x >= cbb.x && p2.x >= cbb.x))
     194        return;
    200195    if (p1.x < caa.x)
    201     {
    202         vec2i m = p2 - p1;
    203 
    204         if (!m.x)
    205             return;
    206         if (m.y)
     196        p1 = p1 + (p2 - p1) * (caa.x - p1.x) / (p2.x - p1.x);
     197    if (p2.x >= cbb.x)
     198        p2 = p1 + (p2 - p1) * (cbb.x - 1 - p1.x) / (p2.x - p1.x);
     199
     200    if (p1.y > p2.y) // make sure that p1.y is on top
     201    {
     202        vec2i tmp = p1; p1 = p2; p2 = tmp; // if not swap points
     203    }
     204
     205    // clip the bottom and top parts
     206    if ((p1.y < caa.y && p2.y < caa.y) || (p1.y >= cbb.y && p2.y >= cbb.y))
     207        return;
     208    if (p2.y >= cbb.y)
     209        p2 = p1 + (p2 - p1) * (cbb.y - 1 - p1.y) / (p2.y - p1.y);
     210    if (p1.y < caa.y)
     211        p1 = p1 + (p2 - p1) * (caa.y - p1.y) / (p2.y - p1.y);
     212
     213    // If we are still outside the clip box, bail out
     214    if (!(p1 >= caa && p2 >= caa && p1 < cbb && p2 < cbb))
     215        return;
     216
     217    // We can now assume p1.y <= p2.y
     218    AddDirty(vec2i(Min(p1.x, p2.x), p1.y),
     219             vec2i(Max(p1.x, p2.x), p2.y) + vec2i(1));
     220
     221    vec2i span = p2 - p1;
     222    int xi = (span.x < 0) ? -1 : 1;
     223    int yi = (span.y < 0) ? -1 : 1;
     224    int n = abs(span.x);
     225    int m = abs(span.y);
     226
     227    uint8_t *start = scan_line(p1.y) + p1.x;
     228
     229    int dx = (n > m) ? yi * m_size.x : xi;
     230    int dy = (n > m) ? xi : yi * m_size.x;
     231    int erx = 2 * Max(span.x * xi, span.y * yi);
     232    int ery = 2 * Min(span.x * xi, span.y * yi);
     233
     234    Lock();
     235    for (int i = 0, er = 0; i <= Max(n, m); i++)
     236    {
     237        *start = color;
     238        if (er > 0)
    207239        {
    208             int b = p1.y - m.y * p1.x / m.x;
    209             p1.y = b + m.y * caa.x / m.x;
    210         }
    211         p1.x = caa.x;
    212     }
    213 
    214     // clip the right side
    215     if (p2.x >= cbb.x)
    216     {
    217         vec2i m = p2 - p1;
    218         if (!m.x)
    219             return;
    220         if (m.y)
    221         {
    222             int b = p1.y - m.y * p1.x / m.x;
    223             p2.y = b + m.y * (cbb.x - 1) / m.x;
    224         }
    225         p2.x = cbb.x - 1;
    226     }
    227 
    228     if (p1.y > p2.y) // make sure that p1.y is on top
    229     {
    230         vec2i tmp = p1; p1 = p2; p2 = tmp; // if not swap points
    231     }
    232 
    233     // clip the bottom
    234     if (p2.y >= cbb.y)
    235     {
    236         vec2i m = p2 - p1;
    237         if (!m.y)
    238             return;
    239         if (m.x)
    240         {
    241             int b = p1.y - (p2.y - p1.y) * p1.x / m.x;
    242             p2.x = (cbb.y - 1 - b) * m.x / m.y;
    243         }
    244         p2.y = cbb.y - 1;
    245     }
    246 
    247     // clip the top
    248     if (p1.y < caa.y)
    249     {
    250         vec2i m = p2 - p1;
    251         if (!m.y)
    252             return;
    253         if (m.x)
    254         {
    255             int b = p1.y - m.y * p1.x / m.x;
    256             p1.x = (caa.y - b) * m.x / m.y;
    257         }
    258         p1.y = caa.y;
    259     }
    260 
    261     // see if it got cliped into the box, out out
    262     if (!(p1 >= caa && p2 >= caa && p1 < cbb && p2 < cbb))
    263         return;
    264 
    265     if (p1.x > p2.x)
    266     {
    267         xc = p2.x;
    268         xi = p1.x;
    269     }
    270     else
    271     {
    272         xi = p2.x;
    273         xc = p1.x;
    274     }
    275 
    276     // assume p1.y <= p2.y from above swap operation
    277     yi = p2.y; yc = p1.y;
    278 
    279     AddDirty(vec2i(xc, yc), vec2i(xi + 1, yi + 1));
    280     dcx = p1.x; dcy = p1.y;
    281     xc = (p2.x - p1.x);
    282     yc = (p2.y - p1.y);
    283     xi = (xc < 0) ? -1 : 1;
    284     yi = (yc < 0) ? -1 : 1;
    285     n = abs(xc);
    286     m = abs(yc);
    287     ycyi = abs(2 * yc * xi);
    288     er = 0;
    289 
    290     Lock();
    291     if (n > m)
    292     {
    293         xcxi = abs(2 * xc * xi);
    294         for (int i = 0; i <= n; i++)
    295         {
    296             scan_line(dcy)[dcx] = color;
    297             if (er > 0)
    298             {
    299                 dcy += yi;
    300                 er -= xcxi;
    301             }
    302             er += ycyi;
    303             dcx += xi;
    304         }
    305     }
    306     else
    307     {
    308         xcyi = abs(2 * xc * yi);
    309         for (int i = 0; i <= m; i++)
    310         {
    311             scan_line(dcy)[dcx] = color;
    312             if (er > 0)
    313             {
    314                 dcx += xi;
    315                 er -= ycyi;
    316             }
    317             er += xcyi;
    318             dcy += yi;
    319         }
     240            start += dx;
     241            er -= erx;
     242        }
     243        er += ery;
     244        start += dy;
    320245    }
    321246    Unlock();
Note: See TracChangeset for help on using the changeset viewer.