⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gxj_putpixel.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 5 页
字号:
 * the exact pixel locations x1,y1 is computed if the leading pixels are clipped * (CLIPPED), the correct major axis ending pixel (+1) is computed xyEnd, * the exact initial Bresenham decision variable and increments (incX,incY) are * computed for clipping and finally an octant flag (REFLECT) is returned if * the segment is on a major Y axis. * * NOTE: Some values (adjIncX,adjIncY) may be changed before OUTSIDE is returned. * IMPL_NOTE: Does MIDP require reversibility, a line (x1,y1)<->(x2,y2) produce *       the same set of pixels in both directions? */static intSetUpClippedLineParams(int *x1, int *y1, int x2, int y2,    int *xyEnd, int *decision, int *incrY, int *incrX,    int *adjIncX, int *adjIncY, const jshort *clip) {  int lineX, lineY, lineEnd, deltaX, deltaY, deltaXtimes2, deltaYtimes2;  int lineX1 = *x1; int lineX2 = x2;  int lineY1 = *y1; int lineY2 = y2;  int clipX1 = clip[0]; int clipX2 = clip[2]-1;  int clipY1 = clip[1]; int clipY2 = clip[3]-1;  int ret = INSIDE;  int tmp, remainder, error;  /* empty clip test */  if ((clipX1 > clipX2) || (clipY1 > clipY2))    return OUTSIDE;  /* start clip testing X axis */  if (lineX1 < lineX2) {    if ((lineX1 > clipX2) || (lineX2 < clipX1))      return OUTSIDE;    /* line is in octant 1,2,7 or 8 */    *adjIncX = 1;  } else {    if ((lineX2 > clipX2) || (lineX1 < clipX1))      return OUTSIDE;    /* line is in octant 3,4,5, or 6 */    *adjIncX = -1;    lineX1 = -lineX1; lineX2 = -lineX2;    clipX1 = -clipX1; clipX2 = -clipX2;    SWAP(clipX1, clipX2);  }  /* start clip testing Y axis */  if (lineY1 < lineY2) {    if ((lineY1 > clipY2) || (lineY2 < clipY1))      return OUTSIDE;    /* line is in octant 1 or 2 */    *adjIncY = 1;  } else {    if ((lineY2 > clipY2) || (lineY1 < clipY1))      return OUTSIDE;    /* line is in octant 7 or 8 */    *adjIncY = -1;    lineY1 = -lineY1; lineY2 = -lineY2;    clipY1 = -clipY1; clipY2 = -clipY2;    SWAP(clipY1, clipY2);  }  /* line has been rotated into octant 1 or 2   * now calculate the bresenham terms */  deltaX = lineX2 - lineX1;  deltaY = lineY2 - lineY1;  if (deltaX < deltaY) {    /* line is in octant 2, reflect into octant 1 */    ret |= REFLECT;    SWAP(lineX1,lineY1); SWAP(lineX2,lineY2); SWAP(deltaX,deltaY);    SWAP(clipX1,clipY1); SWAP(clipX2,clipY2); SWAP(*adjIncX,*adjIncY);  }  if (deltaX == 0) {    /* point at x1, y1 */    return POINT;  }  if (deltaY == 0) {    ret |= HORIZONTAL;    lineX = (lineX1 < clipX1) ? clipX1 : lineX1;    lineY = lineY1;    lineEnd = lineX2;    deltaXtimes2 = 0; deltaYtimes2 = 0;    error = -1;    goto SimpleClipTail;  }  /* IMPL_NOTE: Adjust error by bias (per octant 0/-1)   * to produce symetric line patterns */  deltaXtimes2 = 2*deltaX; deltaYtimes2 = 2*deltaY;  lineX = lineX1; lineY = lineY1;  error = deltaYtimes2 - deltaX;  lineEnd = lineX2;  /* determine where line enters clip */  if (lineY1 < clipY1) {    ret |= CLIPPED;    tmp = deltaXtimes2*(clipY1-lineY1)-deltaX;    lineX += tmp/deltaYtimes2;    remainder = tmp%deltaYtimes2;    if (lineX > clipX2)      return OUTSIDE;    if (lineX/*+1*/ >= clipX1) {      lineY = clipY1;      error -= remainder + deltaX;      if (remainder > 0) {        lineX += 1;        error += deltaYtimes2;      }      goto ClipTail;    }  }  if (lineX1 < clipX1) {    ret |= CLIPPED;    tmp = deltaYtimes2*(clipX1-lineX1);    lineY += tmp/deltaXtimes2;    remainder = tmp%deltaXtimes2;    if ((lineY > clipY2) || (lineY == clipY2 && remainder >= deltaX))      return OUTSIDE;    lineX = clipX1;    error += remainder;    if (remainder >= deltaX) {      lineY += 1;      error -= deltaXtimes2;    }  }ClipTail:  /* clip the tail of the line */  if (lineY2 > clipY2) {    tmp = deltaXtimes2*(clipY2-lineY1)+deltaX;    lineEnd = lineX1+tmp/deltaYtimes2;    remainder = tmp%deltaYtimes2;    if (remainder == 0) /* direct hit on pixel */      lineEnd -= 1;  }  deltaXtimes2 -= deltaYtimes2;SimpleClipTail:  if (lineEnd > clipX2)    lineEnd = clipX2;  lineEnd += 1;  /* reflect line coordinates back into original quadrant */  if (*adjIncY < 0)    lineY = -lineY;  if (*adjIncX < 0) {    lineX = -lineX;    lineEnd = -lineEnd;  }  *x1 = lineX; *y1 = lineY; *xyEnd = lineEnd;  *incrY = deltaXtimes2; *incrX = deltaYtimes2;  *decision = error;  return ret;}/** * Generates pixels for line segments that match the MIDP * specification.  This function generates the set of pixels between * (x1,y1) -> (x2,y2) inclusive, in the order specified.  The * function uses the Bresenham midpoint algorithm.  The set of * pixels generated is within the bounds (CLIP_X1,CLIP_Y1) -> * (CLIP_X2-1,CLIP_Y2-1).  For DOTTED lines the set of generated * pixels is a subset of the pixels generated for SOLID.  The * affect of clipping a DOTTED line is to generate the set of pixels * unclipped and then to remove the pixels beyond the clip bounds. * The maximum and minumum values of pixels and clip bounds are * constrained to avoid an overflow during line segment to clip * bounds calculations. * * @param sbuf Virtual Device Context passed to primDrawPixel * @param color gxj_pixel_type value for generated pixels * @param lineStyle SOLID to generate all pixels or DOTTED for a subset * @param x1,y1 coordinate of first pixel generated must be *              between (-32768 to 32767) inclusive * @param x2,y2 coordinate of the last pixel generated must be *              between (-32768 to 32767) inclusive * @param clip ->clipX1,clipY1,clipX2,clipY2 bounds must be *              between (0 to 32767) inclusive * * Clip constraints: (per the MIDP specification) * if clipX2-1 is less than clipX1 or * if clipY2-1 is less than clipY1 then * the clip bounds are empty and no pixels are generated * */voiddraw_clipped_line(gxj_screen_buffer *sbuf, gxj_pixel_type color,    int lineStyle, const jshort *clip, int x1, int y1, int x2, int y2) {  int incrY, incrX, decision;  int adjIncX, adjIncY;  int xyEnd;  int ret;  int *ptrX, *ptrY;  dotted_draw_state dds; /* for lineStyle == DOTTED */  int x0 = x1;  int y0 = y1;  CHECK_SBUF_CLIP_BOUNDS(sbuf, clip);  ret = SetUpClippedLineParams(&x1, &y1, x2, y2, &xyEnd, &decision,                               &incrY, &incrX, &adjIncX, &adjIncY, clip);  if (ret == OUTSIDE)    return;  if (ret & POINT) {    PRIMDRAWPIXEL(sbuf, color, x1, y1);    return;  }  if (ret & REFLECT) {    ptrX = &y1; ptrY = &x1;  } else {    ptrX = &x1; ptrY = &y1;  }  if (lineStyle == SOLID) {    if ((ret & (HORIZONTAL|REFLECT)) == (HORIZONTAL|REFLECT)) {      CHECK_XY_CLIP(sbuf, *ptrX, *ptrY);      CHECK_XY_CLIP(sbuf, *ptrX, xyEnd-adjIncX);      primDrawVertLine(sbuf, color, *ptrX, *ptrY, *ptrX, xyEnd-adjIncX);      return;    }     if (ret & HORIZONTAL) {      CHECK_XY_CLIP(sbuf, *ptrX, *ptrY);      CHECK_XY_CLIP(sbuf, xyEnd-adjIncX, *ptrY);      primDrawHorzLine(sbuf, color, *ptrX, *ptrY, xyEnd-adjIncX, *ptrY);      return;    }    /* The combination of adjIncX/adjIncY (+1 or -1)     * and REFLECT allow us to use the single octant     * version of the loop for all octants. */    while (x1 != xyEnd) {      PRIMDRAWPIXEL(sbuf, color, *ptrX, *ptrY);      if (decision >= 0) {        y1 += adjIncY; decision -= incrY;      } else {        decision += incrX;      }      x1 += adjIncX;    }    return;  }  dds = START_STROKE;  if (ret & CLIPPED) {    /* compute the offset into pattern compensating for clip */    dds.solidcount = (ret & REFLECT) ? y1 - y0 :  x1 - x0;    if (dds.solidcount < 0)      dds.solidcount = -dds.solidcount;    dds.solidcount %= (DOTTED_SOLID_SIZE+DOTTED_EMPTY_SIZE);    if (dds.solidcount >= DOTTED_SOLID_SIZE) {      dds.drawing = FALSE; dds.emptycount = dds.solidcount-DOTTED_SOLID_SIZE; dds.solidcount = 0;    }  }  while (x1 != xyEnd) {    drawDottedPixel(sbuf, color, *ptrX, *ptrY, &dds);    if (decision >= 0) {      y1 += adjIncY; decision -= incrY;    } else {      decision += incrX;    }    x1 += adjIncX;  }  return;}/** * draw pixels from (x1,y1) through (x1,y2) * y1 should be <= y2, x1 == x2 * coordinates are clipped against the clip */static voiddrawClippedVertLine(const jshort *clip, gxj_screen_buffer *sbuf,    gxj_pixel_type color, int x1, int y1, int x2, int y2) {  const jshort clipX1 = clip[0];  const jshort clipY1 = clip[1];  const jshort clipX2 = clip[2];  const jshort clipY2 = clip[3];  (void)x2;  if (y1 >= clipY2 || y2 <  clipY1 ||      x2 <  clipX1 || x1 >= clipX2)    return;  y1 = (y1 <  clipY1) ? clipY1 : y1;  y2 = (y2 >= clipY2) ? clipY2-1 : y2;  CHECK_XY_CLIP(sbuf, x1, y1); CHECK_XY_CLIP(sbuf, x1, y2);  primDrawVertLine(sbuf, color, x1, y1, x1, y2);}/** * draw pixels from (x1,y1) through (x2,y1) * x1 should be <= x2, y1 == y2 * coordinates are clipped against the clip */static voiddrawClippedHorzLine(const jshort *clip, gxj_screen_buffer *sbuf,    gxj_pixel_type color, int x1, int y1, int x2, int y2) {  const jshort clipX1 = clip[0];  const jshort clipY1 = clip[1];  const jshort clipX2 = clip[2];  const jshort clipY2 = clip[3];  (void)y2;  if (x1 >= clipX2 || x2 <  clipX1 ||      y1 <  clipY1 ||y1 >= clipY2)    return;  x1 = (x1 <  clipX1) ? clipX1 : x1;  x2 = (x2 >= clipX2) ? clipX2-1 : x2;  CHECK_XY_CLIP(sbuf, x1, y1); CHECK_XY_CLIP(sbuf, x2, y1);  primDrawHorzLine(sbuf, color, x1, y1, x2, y1);}/** * Evaluate dotted stroke parameters for the point distant * from the current one by specified number of pixels. * The current point is presented with its stroke state, * i.e. with dds structure (solidcount, emptycount & drawing). * * Note, that stroke can be either solid, or empty line, * while unstroke is considered as a line of the opposite type, * i.e. empty or solid accordingly. * * @param nPixels number of pixels from the current point * @param stroke pointer to the number of pixels drawn already for the *   current stroke, on exit from the method will be evaluated for the *   distant point * @param unstroke if the distant point belongs to a stroke of the *   opposite type than the current point has, this parameter will *   refer to number of pixels already drawn in the distant stroke, *   otherwise it will refer to 0. * @param drawing refers to the stroke type of the current point, *   on return refers to the stroke type of the distant point * @param DOTTED_STROKE_SIZE fixed stroke size of the current stroke type * @param DOTTED_UNSTROKE_SIZE fixed size of the stroke type opposite *   to the current stroke type */static voidSetUpDottedStrokeParamsByPixels(int nPixels,    /*INOUT*/ int *stroke, /*OUT*/ int *unstroke, /*INOUT*/ int *drawing,    const int DOTTED_STROKE_SIZE, const int DOTTED_UNSTROKE_SIZE) {  if (nPixels > DOTTED_STROKE_SIZE - *stroke) {    int offset = (nPixels - DOTTED_STROKE_SIZE + *stroke) %      (DOTTED_STROKE_SIZE + DOTTED_UNSTROKE_SIZE);    if (offset < DOTTED_UNSTROKE_SIZE) {      *drawing = !(*drawing);      *unstroke = offset;      *stroke = 0;    } else {      *stroke = offset - DOTTED_UNSTROKE_SIZE;      *unstroke = 0;    }  } else {    *stroke += nPixels;    *unstroke = 0;  }}/** * Init dotted stroke params for the point distant from * the current point by specified number of pixels. * The current point state is presented by dds. */static voidSetUpDottedParamsByPixels(int nPixels, dotted_draw_state * dds) {    if (dds->drawing) {      SetUpDottedStrokeParamsByPixels(nPixels, &dds->solidcount,  &dds->emptycount,  &dds->drawing,          DOTTED_SOLID_SIZE, DOTTED_EMPTY_SIZE);    } else {      SetUpDottedStrokeParamsByPixels(nPixels,  &dds->emptycount,  &dds->solidcount,  &dds->drawing,          DOTTED_EMPTY_SIZE, DOTTED_SOLID_SIZE);    }}/** * draw dotted pixels from (x1,y1) through (x1,y2) * y1 should be <= y2, x1 == x2 * coordinates are clipped against the clip */static voiddrawClippedDottedVertLine(const jshort *clip, gxj_screen_buffer *sbuf,    gxj_pixel_type color, int x1, int y1, int x2, int y2,    dotted_draw_state dds) {  const jshort clipX1 = clip[0];  const jshort clipY1 = clip[1];  const jshort clipX2 = clip[2];  const jshort clipY2 = clip[3];  (void)x2;  if (y1 >= clipY2 || y2 <  clipY1 ||      x2 <  clipX1 || x1 >= clipX2)    return;  if (y1 < clipY1) {    SetUpDottedParamsByPixels(clipY1 - y1, &dds);    y1 = clipY1;  }  y2 = (y2 >= clipY2) ? clipY2-1 : y2;  CHECK_XY_CLIP(sbuf, x1, y1); CHECK_XY_CLIP(sbuf, x1, y2);  drawDottedVertLine(sbuf, color, x1, y1, x1, y2, dds);}/**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -