for (PRUint32 i=0; i<hsd_len; i++)
for (i=0; i<hsd_len; i++)
scale_imageAntiJag(nsAntiAliasedGlyph *aSrc, nsAntiAliasedGlyph *aDst){  PRUint32 x, y, col;  PRUint8 buffer[65536];  PRUint8 *padded_src = aSrc->GetBuffer();  PRUint8 exp_buffer[65536];  PRUint8 *horizontally_scaled_data = buffer;  PRUint8 *pHsd, *pDst;  PRUint32 dst_width = aDst->GetWidth();  PRUint32 dst_buffer_width = aDst->GetBufferWidth();  PRUint32 dst_height = aDst->GetHeight();  PRUint8 *dst = aDst->GetBuffer();  if (aDst->GetBorder() != 0) {    NS_ASSERTION(aDst->GetBorder()==0, "non zero dest border not supported");    return;  }  int expand = (((dst_width<<8)/aSrc->GetWidth())+255)>>8;  PRUint32 src_width     = aSrc->GetWidth();  PRUint32 src_height    = aSrc->GetHeight();  PRUint32 border_width  = aSrc->GetBorder();  PRUint32 padded_width  = aSrc->GetWidth()  + (2*border_width);  PRUint32 padded_height = aSrc->GetHeight() + (2*border_width);  //  // Expand the data (anti-jagging comes later)  //  PRUint32 expanded_width  = padded_width  * expand;  PRUint32 expanded_height = padded_height * expand;  PRUint32 start_x = border_width * expand;  PRUint32 start_y = border_width * expand;  PRUint8 *expanded_data = exp_buffer;  PRUint32 exp_len = expanded_width*expanded_height;  if (exp_len > sizeof(exp_buffer))    expanded_data = (PRUint8*)malloc(expanded_width*expanded_height);  for (y=0; y<padded_height; y++) {    for (int i=0; i<expand; i++) {      for (x=0; x<padded_width; x++) {        PRUint32 padded_index = x+(y*padded_width);        PRUint32 exp_index = (x*expand) + ((i+(y*expand))*expanded_width);        for (int j=0; j<expand; j++) {          expanded_data[exp_index+j] = padded_src[padded_index];        }      }    }  }  DEBUG_DUMP((dump_byte_table(expanded_data, expanded_width, expanded_height)));// macro to access the surrounding pixels//// +-------+-------+-------+// |  up   |       |  up   |// | left  |  up   | right |// |       |       |       |// +-------+-------+-------+// |       |       |       |// | left  |  SRC  | right |// |       |       |       |// +-------+-------+-------+// |       |       |       |// | down  | down  | down  |// | left  |       | right |// +-------+-------+-------+////#define SRC_UP_LEFT(ps)    *(ps-padded_width-1)#define SRC_UP(ps)         *(ps-padded_width)#define SRC_UP_RIGHT(ps)   *(ps-padded_width+1)#define SRC_LEFT(ps)       *(ps-1)#define SRC(ps)            *(ps)#define SRC_RIGHT(ps)      *(ps+1)#define SRC_DOWN_LEFT(ps)  *(ps+padded_width-1)#define SRC_DOWN(ps)       *(ps+padded_width)#define SRC_DOWN_RIGHT(ps) *(ps+padded_width+1)#define FILL_VALUE 255  //  // Anti-Jag by doing triangular fade-fills and fade clears.  //  // To do a triangular fill/clear the code needs to do a double loop:   //  //    one to scan vertically  //    one to scan horizontally the correct amount to make a triangle  //  // eg:   //  //    for (i=0; i<jag_len; i++)  //      for (j=0; j<jag_len-i; j++)  //  // The way the index is calculated determines whether the triangle is:  // (pseudo code)  //  //      up-right: buf[ j - i*width]  //       up-left: buf[-j - i*width]  //    down-right: buf[ j + i*width]  //     down-left: buf[-j + i*width]  //  // The value to fill-in/clear is related to the distance from the  // origin of this corner. The correct value is the square root  // of the sum of the squares. This code does a rough approximation  // by adding the x and y offsets   //  //    (i+j)  //  // This approximation can darken the fill fade by up to 41% but it  // is much less CPU intensive and does not seem to affect the visual  // quality.  //  // Normalize the value to the 0-1 range (24.8) by dividing by the  // triangle's size:  //  // ((i+j)<<8)/jag_len  //  // Finally convert it to a (8 bit) value  //  // (((((i+j)<<8)/jag_len) * FILL_VALUE) >> 8)  //  // Note: this code only works for black (0) and white (255) values  //  DEBUG_DUMP((dump_byte_table(expanded_data, expanded_width,expanded_height)));  PRUint8 *ps, *es;  PRUint32 jag_len = (expand)/2; // fill/clear one half of the corner  PRUint32 i, j;  for (y=0; y<src_height; y++) {    ps = padded_src + (border_width + (border_width+y)*padded_width);    es = expanded_data         + (border_width+((border_width+y)*expanded_width))*expand;    for (x=0; x<src_width; x++,ps++,es+=expand) {      //      // Fill in the inside of corners      //      if (SRC(ps)==0) {        jag_len = ((expand+1)/2);        if ((SRC_RIGHT(ps)==255) && (SRC_DOWN(ps)==255)) {          // triangular fade fill          for (i=0; i<jag_len; i++)            for (j=0; j<jag_len-i; j++)              es[expand-1-j+((expand-1-i)*expanded_width)] =                            255-(((((i+j)<<8)/jag_len)*FILL_VALUE)>>8);        }        if ((SRC_DOWN(ps)==255) && (SRC_LEFT(ps)==255)) {          // triangular fade fill          for (i=0; i<jag_len; i++)            for (j=0; j<jag_len-i; j++)              es[j+((expand-1-i)*expanded_width)] =                            255-(((((i+j)<<8)/jag_len)*FILL_VALUE)>>8);        }        if ((SRC_LEFT(ps)==255) && (SRC_UP(ps)==255)) {          // triangular fade fill          for (i=0; i<jag_len; i++)            for (j=0; j<jag_len-i; j++)              es[j+(i*expanded_width)] =                            255-(((((i+j)<<8)/jag_len)*FILL_VALUE)>>8);        }        if ((SRC_UP(ps)==255) && (SRC_RIGHT(ps)==255)) {          // triangular fade fill          for (i=0; i<jag_len; i++)            for (j=0; j<jag_len-i; j++)              es[expand-1-j+(i*expanded_width)] =                            255-(((((i+j)<<8)/jag_len)*FILL_VALUE)>>8);        }      }      //      // Round off the outside of corners      else {        jag_len = ((expand+1)/2);        if ((SRC_UP_LEFT(ps)==0) && (SRC_UP(ps)==0) && (SRC_LEFT(ps)==0)) {          // triangular fade clear          for (i=0; i<jag_len; i++)            for (j=0; j<jag_len-i; j++)              es[j+(i*expanded_width)] =                            (((((i+j)<<8)/jag_len)*FILL_VALUE)>>8);        }        if ((SRC_UP(ps)==0) && (SRC_UP_RIGHT(ps)==0) && (SRC_RIGHT(ps)==0)) {          // triangular fade clear          for (i=0; i<jag_len; i++)            for (j=0; j<jag_len-i; j++)              es[expand-1-j+(i*expanded_width)] =                            (((((i+j)<<8)/jag_len)*FILL_VALUE)>>8);        }        if ((SRC_LEFT(ps)==0) && (SRC_DOWN_LEFT(ps)==0) && (SRC_DOWN(ps)==0)) {          // triangular fade clear          for (i=0; i<jag_len; i++)            for (j=0; j<jag_len-i; j++)              es[j+((expand-1-i)*expanded_width)] =                            (((((i+j)<<8)/jag_len)*FILL_VALUE)>>8);        }        if ((SRC_RIGHT(ps)==0) && (SRC_DOWN_RIGHT(ps)==0) && (SRC_DOWN(ps)==0)){          // triangular fade clear          for (i=0; i<jag_len; i++)            for (j=0; j<jag_len-i; j++)              es[(expand-1-j)+((expand-1-i)*expanded_width)] =                            (((((i+j)<<8)/jag_len)*FILL_VALUE)>>8);        }      }    }  }  DEBUG_DUMP((dump_byte_table(expanded_data, expanded_width,expanded_height)));  //  // scale the data horizontally  //  // note: size is +dst_buffer_width because the loop can go one pixel  // (horizontal or vertical) past array (with a near 0 width area)  PRUint32 ratio = ((dst_width<<8)/expand)/src_width;  PRUint32 hsd_len = (dst_buffer_width+1) * expanded_height;  if (hsd_len > sizeof(buffer)) {    horizontally_scaled_data = (PRUint8*)nsMemory::Alloc(hsd_len);    memset(horizontally_scaled_data, 0, hsd_len);  }  for (PRUint32 i=0; i<hsd_len; i++)    horizontally_scaled_data[i] = 0;  PRUint32 len_x   = src_width * expand;  pHsd = horizontally_scaled_data;  for (y=0; y<expanded_height; y++,pHsd+=dst_buffer_width) {    for (x=0; x<len_x; x++) {      PRUint32 exp_index = start_x + x + (y*expanded_width);      PRUint8 src_val = expanded_data[exp_index];      if (!src_val)        continue;      PRUint32 area_begin = x * ratio;      PRUint32 area_end   = (x+1) * ratio;      PRUint32 end_pixel   = (area_end+255)&0xffffff00;      for (col=(area_begin&0xffffff00); col<end_pixel; col+=256) {        PRUint32 this_begin = MAX(col,area_begin);        PRUint32 this_end   = MIN((col+256), area_end);        pHsd[col>>8] += (PRUint8)(((this_end-this_begin)*src_val)>>8);        if ((&pHsd[col>>8]-horizontally_scaled_data) > (int)hsd_len) {          NS_ASSERTION(0, "buffer too small");          return;        }      }    }    DEBUG_DUMP((dump_byte_table(horizontally_scaled_data,                dst_width, expanded_height)));  }  //  // scale the data vertically  //  ratio = ((dst_height<<8)/expand)/src_height;  PRUint32 len_y   = src_height * expand;  for (x=0; x<dst_width; x++) {    pHsd = horizontally_scaled_data + x + (start_y*dst_buffer_width);    pDst = dst + x;    for (y=0; y<len_y; y++,pHsd+=dst_buffer_width) {      PRUint8 src_val = *pHsd;      if (src_val == 0)        continue;      PRUint32 area_begin = y * ratio;      PRUint32 area_end   = area_begin + ratio;      PRUint32 end_pixel   = (area_end+255)&0xffffff00;      PRUint32 c;      PRUint32 col;      for (c=(area_begin>>8)*dst_buffer_width,col=(area_begin&0xffffff00);                  col<end_pixel; c+=dst_buffer_width,col+=256) {        PRUint32 this_begin = MAX(col,area_begin);        PRUint32 this_end   = MIN((col+256), area_end);        PRUint32 val = (((this_end-this_begin)*src_val)>>8);        pDst[c] += val;      }    }    DEBUG_DUMP((dump_byte_table(dst, dst_width, dst_height)));  }  if (expanded_data != exp_buffer)    free(expanded_data);  if (horizontally_scaled_data != buffer)    free(horizontally_scaled_data);}