static void print_parameter(int mode, char *ptr) { #define INSIDE(p,t) (ptr >= (char *) t && ptr < ((char *) t) + sizeof(t)) /* * This is gross, but the best we can do on short notice. */ if (INSIDE(ptr, time_table)) print_time(mode, (CONFIG_TIME_TABLE *) ptr); if (INSIDE(ptr, bool_table)) print_bool(mode, (CONFIG_BOOL_TABLE *) ptr); if (INSIDE(ptr, int_table)) print_int(mode, (CONFIG_INT_TABLE *) ptr); if (INSIDE(ptr, str_table)) print_str(mode, (CONFIG_STR_TABLE *) ptr); if (INSIDE(ptr, str_fn_table)) print_str_fn(mode, (CONFIG_STR_FN_TABLE *) ptr); if (INSIDE(ptr, str_fn_table_2)) print_str_fn_2(mode, (CONFIG_STR_FN_TABLE *) ptr); if (INSIDE(ptr, raw_table)) print_raw(mode, (CONFIG_RAW_TABLE *) ptr); if (INSIDE(ptr, nint_table)) print_nint(mode, (CONFIG_NINT_TABLE *) ptr); if (msg_verbose) vstream_fflush(VSTREAM_OUT); }
void clipline(dcpt winmin,dcpt winmax,wcpt2 p1,wcpt2 p2) { unsigned char encode(wcpt2,dcpt,dcpt); unsigned char code1,code2; int done = 0 , draw = 0; float m; void swapcode(unsigned char *c1,unsigned char *c2); void swappts(wcpt2 *p1,wcpt2 *p2); while(!done) { code1 = encode(p1,winmin,winmax); code2 = encode(p2,winmin,winmax); if(ACCEPT(code1,code2)) { draw = 1; done = 1; } else if(REJECT(code1,code2)) done = 1; else if(INSIDE(code1)) { swappts(&p1,&p2); swapcode(&code1,&code2); } if(code1 & LEFT_EDGE) { p1.y += (winmin.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x); p1.x = winmin.x; } else if(code1 & RIGHT_EDGE) { p1.y += (winmax.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x); p1.x = winmax.x; } else if(code1 & TOP_EDGE) { if(p2.x != p1.x) p1.x += (winmin.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y); p1.y = winmin.y; } else if(code1 & BOTTOM_EDGE) { if(p2.x != p1.x) p1.x += (winmax.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y); p1.y = winmax.y; } } if(draw) { setcolor(5); line(p1.x,p1.y,p2.x,p2.y); } }
static void handle_frame0 (APP *a, XEvent *event) { XButtonPressedEvent *bevent; switch (event->type) { case ButtonPress: bevent = (XButtonPressedEvent *)event; switch (bevent->button & 0xFF) { case Button1: /*printf("handle0: b1\n");*/ if (INSIDE(bevent->x, bevent->y, 4, 4, 10, 10)) { /*printf("next: %d %d\n", bevent->x, bevent->y);*/ break; } if (INSIDE(bevent->x, bevent->y, 50, 4, 56, 10)) { /*printf("quit: %d %d\n", bevent->x, bevent->y);*/ ((DOCKAPP *)a)->quit = True; break; } if (INSIDE(bevent->x, bevent->y, 1, 1, 59, 13)) { /*printf("time: %d %d\n", bevent->x, bevent->y);*/ SWITCH_FRAME(a, 1); break; } if (INSIDE(bevent->x, bevent->y, 1, 16, 59, 27)) { /*printf("cpu : %d %d\n", bevent->x, bevent->y);*/ SWITCH_FRAME(a, 2); break; } if (INSIDE(bevent->x, bevent->y, 1, 30, 29, 41)) { /*printf("wifi: %d %d\n", bevent->x, bevent->y);*/ SWITCH_FRAME(a, 3); break; } if (INSIDE(bevent->x, bevent->y, 32, 30, 59, 41)) { /*printf("temp: %d %d\n", bevent->x, bevent->y);*/ SWITCH_FRAME(a, 4); break; } if (INSIDE(bevent->x, bevent->y, 1, 44, 59, 59)) { /*printf("batt: %d %d\n", bevent->x, bevent->y);*/ SWITCH_FRAME(a, 5); break; } break; case Button2: /*printf("handle0: b2\n");*/ break; case Button3: /*printf("handle0: b3\n");*/ break; } break; } }
Intersection PlanoY::Intercepta(const Raio& r_vis, IntersectionMode mode, float threshold) { float x,z; float t = (a - r_vis.Y0()) / r_vis.Dy(); Intersection lastIntersection; if ( t <0) return lastIntersection; x = r_vis.X0() + t * r_vis.Dx(); if (INSIDE(x,bmin,bmax)) { z = r_vis.Z0() + t *r_vis.Dz(); if (INSIDE(z,cmin,cmax)) { lastIntersection.setValues(this, t); return lastIntersection; } } return lastIntersection; }
/* html_path: * Return a box in a table containing the given endpoint. * If the top flow is text (no internal structure), return * the box of the flow * Else return the box of the subtable containing the point. * Because of spacing, the point might not be in any subtable. * In that case, return the top flow's box. * Note that box[0] must contain the edge point. Additional boxes * move out to the boundary. * * At present, unimplemented, since the label may be inside a * non-box node and we need to figure out what this means. */ int html_path(node_t * n, port* p, int side, box * rv, int *k) { #ifdef UNIMPL point p; tbl_t *info; tbl_t *t; box b; int i; info = (tbl_t *) ND_shape_info(n); assert(info->tbls); info = info->tbls[0]; /* top-level flow */ assert(IS_FLOW(info)); b = info->box; if (info->tbl) { info = info->tbl; if (pt == 1) p = ED_tail_port(e).p; else p = ED_head_port(e).p; p = flip_pt(p, GD_rankdir(n->graph)); /* move p to node's coordinate system */ for (i = 0; (t = info->tbls[i]) != 0; i++) if (INSIDE(p, t->box)) { b = t->box; break; } } /* move box into layout coordinate system */ if (GD_flip(n->graph)) b = flip_trans_box(b, ND_coord_i(n)); else b = move_box(b, ND_coord_i(n)); *k = 1; *rv = b; if (pt == 1) return BOTTOM; else return TOP; #endif return 0; }
static Eterm check_process_code(Process* rp, Module* modp) { Eterm* start; char* mod_start; Uint mod_size; Eterm* end; Eterm* sp; #ifndef HYBRID /* FIND ME! */ ErlFunThing* funp; int done_gc = 0; #endif #define INSIDE(a) (start <= (a) && (a) < end) if (modp == NULL) { /* Doesn't exist. */ return am_false; } else if (modp->old_code == NULL) { /* No old code. */ return am_false; } /* * Pick up limits for the module. */ start = modp->old_code; end = (Eterm *)((char *)start + modp->old_code_length); mod_start = (char *) start; mod_size = modp->old_code_length; /* * Check if current instruction or continuation pointer points into module. */ if (INSIDE(rp->i) || INSIDE(rp->cp)) { return am_true; } /* * Check all continuation pointers stored on the stack. */ for (sp = rp->stop; sp < STACK_START(rp); sp++) { if (is_CP(*sp) && INSIDE(cp_val(*sp))) { return am_true; } } /* * Check all continuation pointers stored in stackdump * and clear exception stackdump if there is a pointer * to the module. */ if (rp->ftrace != NIL) { struct StackTrace *s; ASSERT(is_list(rp->ftrace)); s = (struct StackTrace *) big_val(CDR(list_val(rp->ftrace))); if ((s->pc && INSIDE(s->pc)) || (s->current && INSIDE(s->current))) { rp->freason = EXC_NULL; rp->fvalue = NIL; rp->ftrace = NIL; } else { int i; for (i = 0; i < s->depth; i++) { if (INSIDE(s->trace[i])) { rp->freason = EXC_NULL; rp->fvalue = NIL; rp->ftrace = NIL; break; } } } } /* * See if there are funs that refer to the old version of the module. */ #ifndef HYBRID /* FIND ME! */ rescan: for (funp = MSO(rp).funs; funp; funp = funp->next) { Eterm* fun_code; fun_code = funp->fe->address; if (INSIDE((Eterm *) funp->fe->address)) { if (done_gc) { return am_true; } else { /* * Try to get rid of this fun by garbage collecting. * Clear both fvalue and ftrace to make sure they * don't hold any funs. */ rp->freason = EXC_NULL; rp->fvalue = NIL; rp->ftrace = NIL; done_gc = 1; FLAGS(rp) |= F_NEED_FULLSWEEP; (void) erts_garbage_collect(rp, 0, rp->arg_reg, rp->arity); goto rescan; } } } #endif /* * See if there are constants inside the module referenced by the process. */ done_gc = 0; for (;;) { ErlMessage* mp; if (any_heap_ref_ptrs(&rp->fvalue, &rp->fvalue+1, mod_start, mod_size)) { rp->freason = EXC_NULL; rp->fvalue = NIL; rp->ftrace = NIL; } if (any_heap_ref_ptrs(rp->stop, rp->hend, mod_start, mod_size)) { goto need_gc; } if (any_heap_refs(rp->heap, rp->htop, mod_start, mod_size)) { goto need_gc; } if (any_heap_refs(rp->old_heap, rp->old_htop, mod_start, mod_size)) { goto need_gc; } if (rp->dictionary != NULL) { Eterm* start = rp->dictionary->data; Eterm* end = start + rp->dictionary->used; if (any_heap_ref_ptrs(start, end, mod_start, mod_size)) { goto need_gc; } } for (mp = rp->msg.first; mp != NULL; mp = mp->next) { if (any_heap_ref_ptrs(mp->m, mp->m+2, mod_start, mod_size)) { goto need_gc; } } break; need_gc: if (done_gc) { return am_true; } else { Eterm* literals; Uint lit_size; /* * Try to get rid of constants by by garbage collecting. * Clear both fvalue and ftrace. */ rp->freason = EXC_NULL; rp->fvalue = NIL; rp->ftrace = NIL; done_gc = 1; FLAGS(rp) |= F_NEED_FULLSWEEP; (void) erts_garbage_collect(rp, 0, rp->arg_reg, rp->arity); literals = (Eterm *) modp->old_code[MI_LITERALS_START]; lit_size = (Eterm *) modp->old_code[MI_LITERALS_END] - literals; erts_garbage_collect_literals(rp, literals, lit_size); } } return am_false; #undef INSIDE }
mlib_status __mlib_GraphicsFillArc_AB_32( mlib_image *buffer, mlib_s16 x, mlib_s16 y, mlib_s32 r, mlib_f32 t1, mlib_f32 t2, mlib_s32 c, mlib_s32 a) { mlib_s32 stride = mlib_ImageGetStride(buffer) / sizeof (mlib_s32); mlib_s32 width = mlib_ImageGetWidth(buffer) - 1; mlib_s32 height = mlib_ImageGetHeight(buffer) - 1; mlib_s32 lwidth = width - 1; mlib_s32 lheight = height - 1; mlib_s32 *data = mlib_ImageGetData(buffer); mlib_s32 *line0, *line; mlib_s32 cx, cy, del, mask; mlib_status rez; mlib_s32 stepsignx1, stepsignx2, stepsigny1, stepsigny2; mlib_s32 lineindex1 = 0, lineindex2 = 0; mlib_s32 ifoverlap = 0; mlib_f32 tt1 = t1, tt2 = t2; mlib_s32 sn1, cs1, sn2, cs2; mlib_s32 sin1, cos1, sin2, cos2, oct1, oct2, flagc, flagd; mlib_s32 xx, yy, ux, uy, dx, dy; pinfo buf0[BUFSIZE], *buf = 0; pinfo_line buf0_line1[RADMAX+1], *buf_line1 = 0; pinfo_line buf0_line2[RADMAX+1], *buf_line2 = 0; pinfo_line *buf_line; mlib_s32 count, scount; mlib_s32 start, end; mlib_s32 ind0, ind1, ind2, c0, c1, c2, mdel, k; mlib_s32 alpha0, alpha1, alpha2; mlib_s32 cf0 = c & 0xff, cf1 = (c & 0xff00) >> 8, cf2 = (c & 0xff0000) >> 16; mlib_u8 cfalpha = 0xFF; mlib_d64 A0, A1; a &= 0xff; A1 = a / 255.; A0 = 1. - A1; if (!data) return (MLIB_NULLPOINTER); if (r < 0) return (MLIB_FAILURE); CHECK_INTERSECTION; if (r == 0) { if (INSIDE(x, y)) { BLEND32((data + (stride * y + x))[0], c, a); } return (MLIB_SUCCESS); } if (mlib_fabs(t1 - t2) >= PIx2) { return (__mlib_GraphicsFillCircle_AB_32(buffer, x, y, r, c, a)); } { mlib_f32 tt = t1; t1 = -t2; t2 = -tt; } if (t1 > t2) t2 += PIx2; line0 = data + stride * y + x; if (r > RADMAX) { buf = (pinfo *) __mlib_malloc(sizeof (pinfo) * r); if (!buf) return (MLIB_FAILURE); buf_line1 = (pinfo_line *) __mlib_malloc(sizeof (pinfo_line) * (r + 1)); if (!buf_line1) { __mlib_free(buf); return (MLIB_FAILURE); } buf_line2 = (pinfo_line *) __mlib_malloc(sizeof (pinfo_line) * (r + 1)); if (!buf_line2) { __mlib_free(buf); __mlib_free(buf_line1); return (MLIB_FAILURE); } } else { buf = buf0; buf_line1 = buf0_line1; buf_line2 = buf0_line2; } k = (0x100000 / r); FILL_BUF; GET_BORDERS; if (t1 == t2) { FREE_MEM; return (__mlib_GraphicsDrawLine_AB_32(buffer, x, y, x + cs1, y - sn1, c, a)); } FILL_FLAGS; FILL_CL_FLAGS; SET_STEPSIGN; ARC_FILL_LINEBUF(1); ARC_FILL_LINEBUF(2); start = 0; end = count; PROC_OCT(y, y - height, x - width, x, 2, cos, 1, 2, stride, -1); start = 1; end = count; PROC_OCT(y, y - height, -x, width - x, 1, cos, 2, 1, stride, 1); start = 0; end = count; PROC_OCT(height - y, -y, x - width, x, 5, cos, 2, 1, -stride, -1); start = 1; end = count; PROC_OCT(height - y, -y, -x, width - x, 6, cos, 1, 2, -stride, 1); start = 1; end = scount; PROC_OCT(x, x - width, y - height, y, 3, sin, 2, 1, 1, -stride); start = 0; end = scount; PROC_OCT(x, x - width, -y, height - y, 4, sin, 1, 2, 1, stride); start = 1; end = scount; PROC_OCT(width - x, -x, y - height, y, 0, sin, 1, 2, -1, -stride); start = 0; end = scount; PROC_OCT(width - x, -x, -y, height - y, 7, sin, 2, 1, -1, stride); rez = __mlib_GraphicsFillArc_B_32(buffer, x, y, r - 1, tt1, tt2, c, a); if (rez != MLIB_SUCCESS) { FREE_MEM; return (rez); } DRAW_LINE_AB(1, 2); DRAW_LINE_AB(2, 1); FREE_MEM; return (MLIB_SUCCESS); }
/** * This method checks to see if the given LCD glyph bounds fall within the * cached destination texture bounds. If so, this method can return * immediately. If not, this method will copy a chunk of framebuffer data * into the cached destination texture and then update the current cached * destination bounds before returning. */ static void OGLTR_UpdateCachedDestination(OGLSDOps *dstOps, GlyphInfo *ginfo, jint gx1, jint gy1, jint gx2, jint gy2, jint glyphIndex, jint totalGlyphs) { jint dx1, dy1, dx2, dy2; jint dx1adj, dy1adj; if (isCachedDestValid && INSIDE(gx1, gy1, gx2, gy2, cachedDestBounds)) { // glyph is already within the cached destination bounds; no need // to read back the entire destination region again, but we do // need to see if the current glyph overlaps the previous glyph... if (INTERSECTS(gx1, gy1, gx2, gy2, previousGlyphBounds)) { // the current glyph overlaps the destination region touched // by the previous glyph, so now we need to read back the part // of the destination corresponding to the previous glyph dx1 = previousGlyphBounds.x1; dy1 = previousGlyphBounds.y1; dx2 = previousGlyphBounds.x2; dy2 = previousGlyphBounds.y2; // this accounts for lower-left origin of the destination region dx1adj = dstOps->xOffset + dx1; dy1adj = dstOps->yOffset + dstOps->height - dy2; // copy destination into subregion of cached texture tile: // dx1-cachedDestBounds.x1 == +xoffset from left side of texture // cachedDestBounds.y2-dy2 == +yoffset from bottom of texture j2d_glActiveTextureARB(GL_TEXTURE1_ARB); j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0, dx1 - cachedDestBounds.x1, cachedDestBounds.y2 - dy2, dx1adj, dy1adj, dx2-dx1, dy2-dy1); } } else { jint remainingWidth; // destination region is not valid, so we need to read back a // chunk of the destination into our cached texture // position the upper-left corner of the destination region on the // "top" line of glyph list // REMIND: this isn't ideal; it would be better if we had some idea // of the bounding box of the whole glyph list (this is // do-able, but would require iterating through the whole // list up front, which may present its own problems) dx1 = gx1; dy1 = gy1; if (ginfo->advanceX > 0) { // estimate the width based on our current position in the glyph // list and using the x advance of the current glyph (this is just // a quick and dirty heuristic; if this is a "thin" glyph image, // then we're likely to underestimate, and if it's "thick" then we // may end up reading back more than we need to) remainingWidth = (jint)(ginfo->advanceX * (totalGlyphs - glyphIndex)); if (remainingWidth > OGLTR_CACHED_DEST_WIDTH) { remainingWidth = OGLTR_CACHED_DEST_WIDTH; } else if (remainingWidth < ginfo->width) { // in some cases, the x-advance may be slightly smaller // than the actual width of the glyph; if so, adjust our // estimate so that we can accomodate the entire glyph remainingWidth = ginfo->width; } } else { // a negative advance is possible when rendering rotated text, // in which case it is difficult to estimate an appropriate // region for readback, so we will pick a region that // encompasses just the current glyph remainingWidth = ginfo->width; } dx2 = dx1 + remainingWidth; // estimate the height (this is another sloppy heuristic; we'll // make the cached destination region tall enough to encompass most // glyphs that are small enough to fit in the glyph cache, and then // we add a little something extra to account for descenders dy2 = dy1 + OGLTR_CACHE_CELL_HEIGHT + 2; // this accounts for lower-left origin of the destination region dx1adj = dstOps->xOffset + dx1; dy1adj = dstOps->yOffset + dstOps->height - dy2; // copy destination into cached texture tile (the lower-left corner // of the destination region will be positioned at the lower-left // corner (0,0) of the texture) j2d_glActiveTextureARB(GL_TEXTURE1_ARB); j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dx1adj, dy1adj, dx2-dx1, dy2-dy1); // update the cached bounds and mark it valid cachedDestBounds.x1 = dx1; cachedDestBounds.y1 = dy1; cachedDestBounds.x2 = dx2; cachedDestBounds.y2 = dy2; isCachedDestValid = JNI_TRUE; } // always update the previous glyph bounds previousGlyphBounds.x1 = gx1; previousGlyphBounds.y1 = gy1; previousGlyphBounds.x2 = gx2; previousGlyphBounds.y2 = gy2; }
DMX_TYPE dmxIdentify(char *name) { DMX_TYPE ret=DMX_MPG_UNKNOWN; uint64_t pos; uint8_t stream; FP_TYPE fp=FP_DONT_APPEND; uint64_t size; uint32_t typeES=0,typePS=0; fileParser *parser; parser=new fileParser(); printf("Probing : %s\n",name); if(!parser->open(name,&fp)) { goto _fnd; } // Try to see if it is a TS: if(probeTs(parser)) { delete parser; return DMX_MPG_TS; } parser->setpos(0); while(1) { parser->getpos(&pos); if(pos>MAX_PROBE) goto _nalyze; if(!parser->sync(&stream)) goto _nalyze; #define INSIDE(x,y) (stream>=x && stream<y) if(stream==00 || stream==0xb3 || stream==0xb8) { typeES++; continue; } if( INSIDE(0xE0,0xE9) ) typePS++; } _nalyze: if(typeES>MIN_DETECT) { if(typePS>MIN_DETECT) { printf("%s looks like Mpeg PS (%lu/%lu)\n",name,typeES,typePS); ret=DMX_MPG_PS; } else { printf("%s looks like Mpeg ES (%lu/%lu)\n",name,typeES,typePS); ret=DMX_MPG_ES; } } else { // Try TS here printf("Cannot identify %s as mpeg (%lu/%lu)\n",name,typeES,typePS); } _fnd: delete parser; return ret; }
static int _clipaaline (SDL_Rect *clip, float x1, float _y1, float x2, float y2, float *outpts) { int left = clip->x + 1; int right = clip->x + clip->w - 2; int top = clip->y + 1; int bottom = clip->y + clip->h - 2; int code1, code2; int draw = 0; float swaptmp; int intswaptmp; float m; /*slope*/ if (!outpts) { SDL_SetError ("outpts argument NULL"); return 0; } while (1) { code1 = _fencode (x1, _y1, left, top, right, bottom); code2 = _fencode (x2, y2, left, top, right, bottom); if (ACCEPT (code1, code2)) { draw = 1; break; } else if (REJECT (code1, code2)) break; else { if (INSIDE (code1)) { swaptmp = x2; x2 = x1; x1 = swaptmp; swaptmp = y2; y2 = _y1; _y1 = swaptmp; intswaptmp = code2; code2 = code1; code1 = intswaptmp; } if (x2 != x1) m = (y2 - _y1) / (x2 - x1); else m = 1.0f; if (code1 & LEFT_EDGE) { _y1 += ((float)left - x1) * m; x1 = (float)left; } else if (code1 & RIGHT_EDGE) { _y1 += ((float)right - x1) * m; x1 = (float)right; } else if (code1 & BOTTOM_EDGE) { if (x2 != x1) x1 += ((float)bottom - _y1) / m; _y1 = (float)bottom; } else if (code1 & TOP_EDGE) { if(x2 != x1) x1 += ((float)top - _y1) / m; _y1 = (float)top; } } } if (draw) { outpts[0] = x1; outpts[1] = _y1; outpts[2] = x2; outpts[3] = y2; } return draw; }
/* inBoxf: * Returns true if p is on or in box bb */ static int inBoxf(pointf p, boxf * bb) { return INSIDE(p, *bb); }
void plP_plfclp(PLINT *x, PLINT *y, PLINT npts, PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax, void (*draw) (short *, short *, PLINT)) { PLINT i, xx1, xx2, yy1, yy2; int iclp = 0, iout = 2; short _xclp[2*PL_MAXPOLY+2], _yclp[2*PL_MAXPOLY+2]; short *xclp, *yclp; int drawable; int crossed_xmin1 = 0, crossed_xmax1 = 0; int crossed_ymin1 = 0, crossed_ymax1 = 0; int crossed_xmin2 = 0, crossed_xmax2 = 0; int crossed_ymin2 = 0, crossed_ymax2 = 0; int crossed_up = 0, crossed_down = 0; int crossed_left = 0, crossed_right = 0; int inside_lb ; int inside_lu ; int inside_rb ; int inside_ru ; /* Must have at least 3 points and draw() specified */ if (npts < 3 || !draw) return; if ( npts < PL_MAXPOLY ) { xclp = _xclp; yclp = _yclp; } else { xclp = (short *) malloc( (2*npts+2)*sizeof(short) ) ; yclp = (short *) malloc( (2*npts+2)*sizeof(short) ) ; } inside_lb = pointinpolygon(npts,x,y,xmin,ymin) ; inside_lu = pointinpolygon(npts,x,y,xmin,ymax) ; inside_rb = pointinpolygon(npts,x,y,xmax,ymin) ; inside_ru = pointinpolygon(npts,x,y,xmax,ymax) ; for (i = 0; i < npts - 1; i++) { xx1 = x[i]; xx2 = x[i+1]; yy1 = y[i]; yy2 = y[i+1]; drawable = (INSIDE(xx1, yy1) && INSIDE(xx2, yy2)); if ( ! drawable) drawable = ! clipline(&xx1, &yy1, &xx2, &yy2, xmin, xmax, ymin, ymax); if (drawable) { /* Boundary crossing condition -- coming in. */ crossed_xmin2 = (xx1 == xmin); crossed_xmax2 = (xx1 == xmax); crossed_ymin2 = (yy1 == ymin); crossed_ymax2 = (yy1 == ymax); crossed_left = (crossed_left || crossed_xmin2); crossed_right = (crossed_right || crossed_xmax2); crossed_down = (crossed_down || crossed_ymin2); crossed_up = (crossed_up || crossed_ymax2); iout = iclp+2; /* If the first segment, just add it. */ if (iclp == 0) { xclp[iclp] = xx1; yclp[iclp] = yy1; iclp++; xclp[iclp] = xx2; yclp[iclp] = yy2; iclp++; } /* Not first point. If first point of this segment matches up to the previous point, just add it. */ else if (xx1 == xclp[iclp-1] && yy1 == yclp[iclp-1]) { xclp[iclp] = xx2; yclp[iclp] = yy2; iclp++; } /* Otherwise, we need to add both points, to connect the points in the * polygon along the clip boundary. If we encircled a corner, we have * to add that first. */ else { /* Treat the case where we encircled two corners: Construct a polygon out of the subset of vertices Note that the direction is important too when adding the extra points */ xclp[iclp+1] = xx2; yclp[iclp+1] = yy2; xclp[iclp+2] = xx1; yclp[iclp+2] = yy1; iout = iout - iclp + 1; /* Upper two */ if ( ((crossed_xmin1 && crossed_xmax2) || (crossed_xmin2 && crossed_xmax1)) && inside_lu ) { if ( crossed_xmin1 ) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } } /* Lower two */ else if ( ((crossed_xmin1 && crossed_xmax2) || (crossed_xmin2 && crossed_xmax1)) && inside_lb ) { if ( crossed_xmin1 ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } } /* Left two */ else if ( ((crossed_ymin1 && crossed_ymax2) || (crossed_ymin2 && crossed_ymax1)) && inside_lb ) { if ( crossed_ymin1 ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } } /* Right two */ else if ( ((crossed_ymin1 && crossed_ymax2) || (crossed_ymin2 && crossed_ymax1)) && inside_rb ) { if ( crossed_ymin1 ) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } } /* Now the case where we encircled one corner */ /* Lower left */ else if ( (crossed_xmin1 && crossed_ymin2) || (crossed_ymin1 && crossed_xmin2) ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } /* Lower right */ else if ( (crossed_xmax1 && crossed_ymin2) || (crossed_ymin1 && crossed_xmax2) ) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } /* Upper left */ else if ( (crossed_xmin1 && crossed_ymax2) || (crossed_ymax1 && crossed_xmin2) ) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } /* Upper right */ else if ( (crossed_xmax1 && crossed_ymax2) || (crossed_ymax1 && crossed_xmax2) ) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } /* Now add current segment. */ xclp[iclp] = xx1; yclp[iclp] = yy1; iclp++; xclp[iclp] = xx2; yclp[iclp] = yy2; iclp++; } /* Boundary crossing condition -- going out. */ crossed_xmin1 = (xx2 == xmin); crossed_xmax1 = (xx2 == xmax); crossed_ymin1 = (yy2 == ymin); crossed_ymax1 = (yy2 == ymax); } } /* Limit case - all vertices are outside of bounding box. So just fill entire box, *if* the bounding box is completely encircled. */ if (iclp == 0) { PLINT xmin1, xmax1, ymin1, ymax1; xmin1 = xmax1 = x[0]; ymin1 = ymax1 = y[0]; for (i = 1; i < npts; i++) { if (x[i] < xmin1) xmin1 = x[i]; if (x[i] > xmax1) xmax1 = x[i]; if (y[i] < ymin1) ymin1 = y[i]; if (y[i] > ymax1) ymax1 = y[i]; } if (xmin1 <= xmin && xmax1 >= xmax && ymin1 <= ymin && ymax1 >= ymax ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; (*draw)(xclp, yclp, iclp); if ( xclp != _xclp ) { free( xclp ); free( yclp ); } return; } } /* Now handle cases where fill polygon intersects two sides of the box */ if (iclp >= 2) { int debug=0; int dir = circulation(x, y, npts); if (debug) { if ( (xclp[0] == xmin && xclp[iclp-1] == xmax) || (xclp[0] == xmax && xclp[iclp-1] == xmin) || (yclp[0] == ymin && yclp[iclp-1] == ymax) || (yclp[0] == ymax && yclp[iclp-1] == ymin) || (xclp[0] == xmin && yclp[iclp-1] == ymin) || (yclp[0] == ymin && xclp[iclp-1] == xmin) || (xclp[0] == xmax && yclp[iclp-1] == ymin) || (yclp[0] == ymin && xclp[iclp-1] == xmax) || (xclp[0] == xmax && yclp[iclp-1] == ymax) || (yclp[0] == ymax && xclp[iclp-1] == xmax) || (xclp[0] == xmin && yclp[iclp-1] == ymax) || (yclp[0] == ymax && xclp[iclp-1] == xmin) ) { printf("dir=%d, clipped points:\n", dir); for (i=0; i < iclp; i++) printf(" x[%d]=%d y[%d]=%d", i, xclp[i], i, yclp[i]); printf("\n"); printf("pre-clipped points:\n"); for (i=0; i < npts; i++) printf(" x[%d]=%d y[%d]=%d", i, x[i], i, y[i]); printf("\n"); } } /* The cases where the fill region is divided 2/2 */ /* Divided horizontally */ if (xclp[0] == xmin && xclp[iclp-1] == xmax) { if (dir > 0) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } } else if (xclp[0] == xmax && xclp[iclp-1] == xmin) { if (dir > 0) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } else { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } } /* Divided vertically */ else if (yclp[0] == ymin && yclp[iclp-1] == ymax) { if (dir > 0) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } } else if (yclp[0] == ymax && yclp[iclp-1] == ymin) { if (dir > 0) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } } /* The cases where the fill region is divided 3/1 -- LL LR UR UL +-----+ +-----+ +-----+ +-----+ | | | | | \| |/ | | | | | | | | | |\ | | /| | | | | +-----+ +-----+ +-----+ +-----+ Note when we go the long way around, if the direction is reversed the three vertices must be visited in the opposite order. */ /* LL, short way around */ else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir < 0) || (yclp[0] == ymin && xclp[iclp-1] == xmin && dir > 0) ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } /* LL, long way around, counterclockwise */ else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir > 0)) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } /* LL, long way around, clockwise */ else if ((yclp[0] == ymin && xclp[iclp-1] == xmin && dir < 0)) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } /* LR, short way around */ else if ((xclp[0] == xmax && yclp[iclp-1] == ymin && dir > 0) || (yclp[0] == ymin && xclp[iclp-1] == xmax && dir < 0) ) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } /* LR, long way around, counterclockwise */ else if (yclp[0] == ymin && xclp[iclp-1] == xmax && dir > 0) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } /* LR, long way around, clockwise */ else if (xclp[0] == xmax && yclp[iclp-1] == ymin && dir < 0) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } /* UR, short way around */ else if ((xclp[0] == xmax && yclp[iclp-1] == ymax && dir < 0) || (yclp[0] == ymax && xclp[iclp-1] == xmax && dir > 0) ) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } /* UR, long way around, counterclockwise */ else if (xclp[0] == xmax && yclp[iclp-1] == ymax && dir > 0) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } /* UR, long way around, clockwise */ else if (yclp[0] == ymax && xclp[iclp-1] == xmax && dir < 0) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } /* UL, short way around */ else if ((xclp[0] == xmin && yclp[iclp-1] == ymax && dir > 0) || (yclp[0] == ymax && xclp[iclp-1] == xmin && dir < 0) ) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } /* UL, long way around, counterclockwise */ else if (yclp[0] == ymax && xclp[iclp-1] == xmin && dir > 0) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } /* UL, long way around, clockwise */ else if (xclp[0] == xmin && yclp[iclp-1] == ymax && dir < 0) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } } /* Check for the case that only one side has been crossed (AM) Just checking a single point turns out not to be enough, apparently the crossed_*1 and crossed_*2 variables are not quite what I expected. */ if ( crossed_left+crossed_right+crossed_down+crossed_up == 1 && inside_lb+inside_rb+inside_lu+inside_ru == 4 ) { int dir = circulation(x, y, npts); PLINT xlim[4], ylim[4]; int insert; int incr; xlim[0] = xmin ; ylim[0] = ymin ; xlim[1] = xmax ; ylim[1] = ymin ; xlim[2] = xmax ; ylim[2] = ymax ; xlim[3] = xmin ; ylim[3] = ymax ; if ( dir > 0 ) { incr = 1; insert = 0*crossed_left + 1*crossed_down + 2*crossed_right + 3*crossed_up ; } else { incr = -1; insert = 3*crossed_left + 2*crossed_up + 1*crossed_right + 0*crossed_down ; } for ( i=0; i < 4; i ++ ) { xclp[iclp] = xlim[insert] ; yclp[iclp] = ylim[insert] ; iclp ++ ; insert += incr ; if ( insert > 3 ) insert = 0 ; if ( insert < 0 ) insert = 3 ; } } /* Draw the sucker */ if (iclp >= 3) (*draw)(xclp, yclp, iclp); if ( xclp != _xclp ) { free( xclp ); free( yclp ); } }
void plP_pllclp(PLINT *x, PLINT *y, PLINT npts, PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax, void (*draw) (short *, short *, PLINT)) { PLINT xx1, xx2, yy1, yy2; PLINT i, iclp = 0; short _xclp[PL_MAXPOLY], _yclp[PL_MAXPOLY]; short *xclp, *yclp; int drawable; if ( npts < PL_MAXPOLY ) { xclp = _xclp; yclp = _yclp; } else { xclp = (short *) malloc( npts*sizeof(short) ) ; yclp = (short *) malloc( npts*sizeof(short) ) ; } for (i = 0; i < npts - 1; i++) { xx1 = x[i]; xx2 = x[i + 1]; yy1 = y[i]; yy2 = y[i + 1]; drawable = (INSIDE(xx1, yy1) && INSIDE(xx2, yy2)); if ( ! drawable) drawable = ! clipline(&xx1, &yy1, &xx2, &yy2, xmin, xmax, ymin, ymax); if (drawable) { /* First point of polyline. */ if (iclp == 0) { xclp[iclp] = xx1; yclp[iclp] = yy1; iclp++; xclp[iclp] = xx2; yclp[iclp] = yy2; } /* Not first point. Check if first point of this segment matches up to previous point, and if so, add it to the current polyline buffer. */ else if (xx1 == xclp[iclp] && yy1 == yclp[iclp]) { iclp++; xclp[iclp] = xx2; yclp[iclp] = yy2; } /* Otherwise it's time to start a new polyline */ else { if (iclp + 1 >= 2) (*draw)(xclp, yclp, iclp + 1); iclp = 0; xclp[iclp] = xx1; yclp[iclp] = yy1; iclp++; xclp[iclp] = xx2; yclp[iclp] = yy2; } } } /* Handle remaining polyline */ if (iclp + 1 >= 2) (*draw)(xclp, yclp, iclp + 1); plsc->currx = x[npts-1]; plsc->curry = y[npts-1]; if ( xclp != _xclp ) { free( xclp ); free( yclp ); } }
static struct i_bitmap * i_flood_fill_low(i_img *im,i_img_dim seedx,i_img_dim seedy, i_img_dim *bxminp, i_img_dim *bxmaxp, i_img_dim *byminp, i_img_dim *bymaxp, i_color const *seed, ff_cmpfunc cmpfunc) { i_img_dim ltx, rtx; i_img_dim tx = 0; i_img_dim bxmin = seedx; i_img_dim bxmax = seedx; i_img_dim bymin = seedy; i_img_dim bymax = seedy; struct llist *st; struct i_bitmap *btm; int channels; i_img_dim xsize,ysize; i_color cval; channels = im->channels; xsize = im->xsize; ysize = im->ysize; btm = btm_new(xsize, ysize); st = llist_new(100, sizeof(struct stack_element*)); /* Find the starting span and fill it */ ltx = i_lspan(im, seedx, seedy, seed, cmpfunc); rtx = i_rspan(im, seedx, seedy, seed, cmpfunc); for(tx=ltx; tx<=rtx; tx++) SET(tx, seedy); bxmin = ltx; bxmax = rtx; ST_PUSH(ltx, rtx, ltx, rtx, seedy+1, 1); ST_PUSH(ltx, rtx, ltx, rtx, seedy-1, -1); while(st->count) { /* Stack variables */ i_img_dim lx,rx; i_img_dim dadLx,dadRx; i_img_dim y; int direction; i_img_dim x; int wasIn=0; ST_POP(); /* sets lx, rx, dadLx, dadRx, y, direction */ if (y<0 || y>ysize-1) continue; if (bymin > y) bymin=y; /* in the worst case an extra line */ if (bymax < y) bymax=y; x = lx+1; if ( lx >= 0 && (wasIn = INSIDE(lx, y, seed)) ) { SET(lx, y); lx--; while(lx >= 0 && INSIDE(lx, y, seed)) { SET(lx,y); lx--; } } if (bxmin > lx) bxmin = lx; while(x <= xsize-1) { /* printf("x=%d\n",x); */ if (wasIn) { if (INSIDE(x, y, seed)) { /* case 1: was inside, am still inside */ SET(x,y); } else { /* case 2: was inside, am no longer inside: just found the right edge of a span */ ST_STACK(direction, dadLx, dadRx, lx, (x-1), y); if (bxmax < x) bxmax = x; wasIn=0; } } else { if (x > rx) goto EXT; if (INSIDE(x, y, seed)) { SET(x, y); /* case 3: Wasn't inside, am now: just found the start of a new run */ wasIn = 1; lx = x; } else { /* case 4: Wasn't inside, still isn't */ } } x++; } EXT: /* out of loop */ if (wasIn) { /* hit an edge of the frame buffer while inside a run */ ST_STACK(direction, dadLx, dadRx, lx, (x-1), y); if (bxmax < x) bxmax = x; } } llist_destroy(st); *bxminp = bxmin; *bxmaxp = bxmax; *byminp = bymin; *bymaxp = bymax; return btm; }
static LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static int penDown = JAVACALL_FALSE; int x, y; int i; PAINTSTRUCT ps; HDC hdc; HANDLE *mutex; int key; //check if udp or tcp int level = SOL_SOCKET; int opttarget; int optname; int optsize = sizeof(optname); switch(iMsg) { #ifdef SKINS_MENU_SUPPORTED case WM_COMMAND: switch(wParam & 0xFFFF) { case EXMENU_ITEM_SHUTDOWN: printf("EXMENU_ITEM_SHUTDOWN ... \n"); javanotify_shutdown(); break; case EXMENU_ITEM_PAUSE: javanotify_pause(); break; case EXMENU_ITEM_RESUME: javanotify_resume(); break; default: return DefWindowProc (hwnd, iMsg, wParam, lParam); } /* end of switch */ return 0; #endif case WM_CREATE: hdc = GetDC(hwnd); CHECK_RETURN(SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT))); GetTextMetrics(hdc, &fixed_tm); CHECK_RETURN(SelectObject(hdc, GetStockObject(SYSTEM_FONT))); GetTextMetrics(hdc, &tm); ReleaseDC(hwnd, hdc); return 0; case WM_PAINT: mutex = (HANDLE*) TlsGetValue(tlsId); WaitForSingleObject(*mutex, INFINITE); hdc = BeginPaint(hwnd, &ps); /* * There are 3 bitmap buffers, putpixel screen buffer, the phone * bitmap and the actual window buffer. Paint the phone bitmap on the * window. LCDUIrefresh has already painted the putpixel buffer on the * LCD screen area of the phone bitmap. * * On a real win32 (or high level window API) device the phone bitmap * would not be needed the code below would just paint the putpixel * buffer the window. */ DrawBitmap(hdc, hPhoneBitmap, 0, 0, SRCCOPY); EndPaint(hwnd, &ps); ReleaseMutex(*mutex); return 0; case WM_CLOSE: /* * Handle the "X" (close window) button by sending the AMS a shutdown * event. */ #ifdef SKINS_MENU_SUPPORTED destroySkinsMenu(); #endif javanotify_shutdown(); PostQuitMessage(0); return 0; case WM_SYSKEYDOWN: case WM_SYSKEYUP: /* The only event of this type that we want MIDP * to handle is the F10 key which for some reason is not * sent in the WM_KEY messages. * if we receive any other key in this message, break. */ if(wParam != VK_F10) { break; } // patch for VK_F10 if (WM_SYSKEYUP == iMsg) { iMsg = WM_KEYUP; } else if (WM_SYSKEYDOWN == iMsg) { iMsg = WM_KEYDOWN; } /* fall through */ case WM_KEYDOWN: { /* Impl note: to send pause and resume notifications */ static int isPaused; if(VK_F5 == wParam) { if(!isPaused) { javanotify_pause(); } else { javanotify_resume(); } isPaused =!isPaused; break; } else if(VK_HOME == wParam) { javanotify_switch_to_ams(); break; } else if(VK_F4 == wParam) { javanotify_select_foreground_app(); break; /* F3 key used for rotation. */ } else if(VK_F3 == wParam) { javanotify_rotation(); } } case WM_KEYUP: key = mapKey(wParam, lParam); switch(key) { case /* MIDP_KEY_INVALID */ 0: return 0; /* case MD_KEY_HOME: if (iMsg == WM_KEYDOWN) { return 0; } pMidpEventResult->type = SELECT_FOREGROUND_EVENT; pSignalResult->waitingFor = AMS_SIGNAL; return 0; */ default: break; } if(iMsg == WM_KEYUP) { javanotify_key_event((javacall_key)key, JAVACALL_KEYRELEASED); } else if(iMsg == WM_KEYDOWN) { if (lParam & 0xf0000000) { javanotify_key_event((javacall_key)key, JAVACALL_KEYREPEATED); } else { javanotify_key_event((javacall_key)key, JAVACALL_KEYPRESSED); } } return 0; case WM_TIMER: // Stop the timer from repeating the WM_TIMER message. KillTimer(hwnd, wParam); return 0; case WM_MOUSEMOVE: case WM_LBUTTONDOWN: case WM_LBUTTONUP: /* Cast lParam to "short" to preserve sign */ x = (short)LOWORD(lParam); y = (short)HIWORD(lParam); /** please uncomment following line if you want to test pen input in win32 emulator. ** with ENABLE_PEN_EVENT_NOTIFICATION defined, you should also modify constants.xml ** in midp workspace in order to pass related tck cases. **/ #define ENABLE_PEN_EVENT_NOTIFICATION 1 #ifdef ENABLE_PEN_EVENT_NOTIFICATION midpScreen_bounds.x = x_offset; midpScreen_bounds.y = y_offset; midpScreen_bounds.width = VRAM.width; midpScreen_bounds.height = (inFullScreenMode? VRAM.height: VRAM.height - TOP_BAR_HEIGHT); if(iMsg == WM_LBUTTONDOWN && INSIDE(x, y, midpScreen_bounds) ) { penAreDragging = JAVACALL_TRUE; SetCapture(hwnd); if (reverse_orientation) { javanotify_pen_event(javacall_lcd_get_screen_width() - y + y_offset, x - x_offset, JAVACALL_PENPRESSED); } else { javanotify_pen_event(x-x_offset, y-y_offset, JAVACALL_PENPRESSED); } return 0; } if(iMsg == WM_LBUTTONUP && (INSIDE(x, y, midpScreen_bounds) || penAreDragging == JAVACALL_TRUE)) { if(penAreDragging == JAVACALL_TRUE) { penAreDragging = JAVACALL_FALSE; ReleaseCapture(); } if (reverse_orientation) { javanotify_pen_event(javacall_lcd_get_screen_width() - y + y_offset, x - x_offset, JAVACALL_PENRELEASED); } else { javanotify_pen_event(x-x_offset, y-y_offset, JAVACALL_PENRELEASED); } return 0; } if(iMsg == WM_MOUSEMOVE) { if(penAreDragging == JAVACALL_TRUE) { if (reverse_orientation) { javanotify_pen_event(javacall_lcd_get_screen_width() - y + y_offset, x - x_offset, JAVACALL_PENDRAGGED); } else { javanotify_pen_event(x-x_offset, y-y_offset, JAVACALL_PENDRAGGED); } } return 0; } #else if(iMsg == WM_MOUSEMOVE) { /* * Don't process mouse move messages that are not over the LCD * screen of the skin. */ return 0; } #endif for(i = 0; i < NUMBEROF(Keys); ++i) { if(!(INSIDE(x, y, Keys[i].bounds))) { continue; } /* Chameleon processes keys on the way down. */ #ifdef SOUND_SUPPORTED if(iMsg == WM_LBUTTONDOWN) { MessageBeep(MB_OK); } #endif switch(Keys[i].button) { case KEY_POWER: if(iMsg == WM_LBUTTONUP) { return 0; } javanotify_shutdown(); return 0; case KEY_END: if(iMsg == WM_LBUTTONUP) { return 0; } /* NEED REVISIT: destroy midlet instead of shutdown? */ javanotify_shutdown(); return 0; default: /* Handle the simulated key events. */ switch(iMsg) { case WM_LBUTTONDOWN: javanotify_key_event((javacall_key)Keys[i].button, JAVACALL_KEYPRESSED); return 0; case WM_LBUTTONUP: javanotify_key_event((javacall_key)Keys[i].button, JAVACALL_KEYRELEASED); return 0; default: break; } /* switch iMsg */ } /* switch key */ } /* for */ return 0; case WM_NETWORK: #ifdef ENABLE_NETWORK_TRACING fprintf(stderr, "Got WM_NETWORK("); fprintf(stderr, "descriptor = %d, ", (int)wParam); fprintf(stderr, "status = %d, ", WSAGETSELECTERROR(lParam)); #endif optname = SO_TYPE; if(0 != getsockopt((SOCKET)wParam, SOL_SOCKET, optname,(char*)&opttarget, &optsize)) { #ifdef ENABLE_NETWORK_TRACING fprintf(stderr, "getsocketopt error)\n"); #endif } if(opttarget == SOCK_STREAM) { // TCP socket return handleNetworkStreamEvents(wParam,lParam); } else { return handleNetworkDatagramEvents(wParam,lParam); }; break; case WM_HOST_RESOLVED: #ifdef ENABLE_TRACE_NETWORKING fprintf(stderr, "Got Windows event WM_HOST_RESOLVED \n"); #endif javanotify_socket_event( JAVACALL_EVENT_NETWORK_GETHOSTBYNAME_COMPLETED, (javacall_handle)wParam, (WSAGETSELECTERROR(lParam) == 0) ? JAVACALL_OK : JAVACALL_FAIL); return 0; #if 0 /* media */ case WM_DEBUGGER: pSignalResult->waitingFor = VM_DEBUG_SIGNAL; return 0; case WM_MEDIA: pSignalResult->waitingFor = MEDIA_EVENT_SIGNAL; pSignalResult->descriptor = (int)wParam; pSignalResult->pResult = (void*)lParam; return 0; #endif /* media */ default: break; } /* end of external switch */ return DefWindowProc (hwnd, iMsg, wParam, lParam); } /* end of WndProc */
/** * This method checks to see if the given LCD glyph bounds fall within the * cached destination texture bounds. If so, this method can return * immediately. If not, this method will copy a chunk of framebuffer data * into the cached destination texture and then update the current cached * destination bounds before returning. * * The agx1, agx2 are "adjusted" glyph bounds, which are only used when checking * against the previous glyph bounds. */ static HRESULT D3DTR_UpdateCachedDestination(D3DContext *d3dc, D3DSDOps *dstOps, GlyphInfo *ginfo, jint gx1, jint gy1, jint gx2, jint gy2, jint agx1, jint agx2, jint glyphIndex, jint totalGlyphs) { jint dx1, dy1, dx2, dy2; D3DResource *pCachedDestTexRes; IDirect3DSurface9 *pCachedDestSurface, *pDst; HRESULT res; if (isCachedDestValid && INSIDE(gx1, gy1, gx2, gy2, cachedDestBounds)) { // glyph is already within the cached destination bounds; no need // to read back the entire destination region again, but we do // need to see if the current glyph overlaps the previous glyph... // only use the "adjusted" glyph bounds when checking against // previous glyph's bounds gx1 = agx1; gx2 = agx2; if (INTERSECTS(gx1, gy1, gx2, gy2, previousGlyphBounds)) { // the current glyph overlaps the destination region touched // by the previous glyph, so now we need to read back the part // of the destination corresponding to the previous glyph dx1 = previousGlyphBounds.x1; dy1 = previousGlyphBounds.y1; dx2 = previousGlyphBounds.x2; dy2 = previousGlyphBounds.y2; // REMIND: make sure we flush any pending primitives that are // dependent on the current contents of the cached dest d3dc->FlushVertexQueue(); RETURN_STATUS_IF_NULL(dstOps->pResource, E_FAIL); RETURN_STATUS_IF_NULL(pDst = dstOps->pResource->GetSurface(), E_FAIL); res = d3dc->GetResourceManager()-> GetCachedDestTexture(dstOps->pResource->GetDesc()->Format, &pCachedDestTexRes); RETURN_STATUS_IF_FAILED(res); pCachedDestSurface = pCachedDestTexRes->GetSurface(); // now dxy12 represent the "desired" destination bounds, but the // StretchRect() call may fail if these fall outside the actual // surface bounds; therefore, we use cxy12 to represent the // clamped bounds, and dxy12 are saved for later jint cx1 = (dx1 < 0) ? 0 : dx1; jint cy1 = (dy1 < 0) ? 0 : dy1; jint cx2 = (dx2 > dstOps->width) ? dstOps->width : dx2; jint cy2 = (dy2 > dstOps->height) ? dstOps->height : dy2; if (cx2 > cx1 && cy2 > cy1) { // copy destination into subregion of cached texture tile // cx1-cachedDestBounds.x1 == +xoffset from left of texture // cy1-cachedDestBounds.y1 == +yoffset from top of texture // cx2-cachedDestBounds.x1 == +xoffset from left of texture // cy2-cachedDestBounds.y1 == +yoffset from top of texture jint cdx1 = cx1-cachedDestBounds.x1; jint cdy1 = cy1-cachedDestBounds.y1; jint cdx2 = cx2-cachedDestBounds.x1; jint cdy2 = cy2-cachedDestBounds.y1; RECT srcRect = { cx1, cy1, cx2, cy2 }; RECT dstRect = { cdx1, cdy1, cdx2, cdy2 }; IDirect3DDevice9 *pd3dDevice = d3dc->Get3DDevice(); res = pd3dDevice->StretchRect(pDst, &srcRect, pCachedDestSurface, &dstRect, D3DTEXF_NONE); } } } else { // destination region is not valid, so we need to read back a // chunk of the destination into our cached texture // position the upper-left corner of the destination region on the // "top" line of glyph list // REMIND: this isn't ideal; it would be better if we had some idea // of the bounding box of the whole glyph list (this is // do-able, but would require iterating through the whole // list up front, which may present its own problems) dx1 = gx1; dy1 = gy1; jint remainingWidth; if (ginfo->advanceX > 0) { // estimate the width based on our current position in the glyph // list and using the x advance of the current glyph (this is just // a quick and dirty heuristic; if this is a "thin" glyph image, // then we're likely to underestimate, and if it's "thick" then we // may end up reading back more than we need to) remainingWidth = (jint)(ginfo->advanceX * (totalGlyphs - glyphIndex)); if (remainingWidth > D3DTR_CACHED_DEST_WIDTH) { remainingWidth = D3DTR_CACHED_DEST_WIDTH; } else if (remainingWidth < ginfo->width) { // in some cases, the x-advance may be slightly smaller // than the actual width of the glyph; if so, adjust our // estimate so that we can accomodate the entire glyph remainingWidth = ginfo->width; } } else { // a negative advance is possible when rendering rotated text, // in which case it is difficult to estimate an appropriate // region for readback, so we will pick a region that // encompasses just the current glyph remainingWidth = ginfo->width; } dx2 = dx1 + remainingWidth; // estimate the height (this is another sloppy heuristic; we'll // make the cached destination region tall enough to encompass most // glyphs that are small enough to fit in the glyph cache, and then // we add a little something extra to account for descenders dy2 = dy1 + D3DTR_CACHE_CELL_HEIGHT + 2; // REMIND: make sure we flush any pending primitives that are // dependent on the current contents of the cached dest d3dc->FlushVertexQueue(); RETURN_STATUS_IF_NULL(dstOps->pResource, E_FAIL); RETURN_STATUS_IF_NULL(pDst = dstOps->pResource->GetSurface(), E_FAIL); res = d3dc->GetResourceManager()-> GetCachedDestTexture(dstOps->pResource->GetDesc()->Format, &pCachedDestTexRes); RETURN_STATUS_IF_FAILED(res); pCachedDestSurface = pCachedDestTexRes->GetSurface(); // now dxy12 represent the "desired" destination bounds, but the // StretchRect() call may fail if these fall outside the actual // surface bounds; therefore, we use cxy12 to represent the // clamped bounds, and dxy12 are saved for later jint cx1 = (dx1 < 0) ? 0 : dx1; jint cy1 = (dy1 < 0) ? 0 : dy1; jint cx2 = (dx2 > dstOps->width) ? dstOps->width : dx2; jint cy2 = (dy2 > dstOps->height) ? dstOps->height : dy2; if (cx2 > cx1 && cy2 > cy1) { // copy destination into cached texture tile (the upper-left // corner of the destination region will be positioned at the // upper-left corner (0,0) of the texture) RECT srcRect = { cx1, cy1, cx2, cy2 }; RECT dstRect = { cx1-dx1, cy1-dy1, cx2-dx1, cy2-dy1 }; IDirect3DDevice9 *pd3dDevice = d3dc->Get3DDevice(); res = pd3dDevice->StretchRect(pDst, &srcRect, pCachedDestSurface, &dstRect, D3DTEXF_NONE); } // update the cached bounds and mark it valid cachedDestBounds.x1 = dx1; cachedDestBounds.y1 = dy1; cachedDestBounds.x2 = dx2; cachedDestBounds.y2 = dy2; isCachedDestValid = JNI_TRUE; } // always update the previous glyph bounds previousGlyphBounds.x1 = gx1; previousGlyphBounds.y1 = gy1; previousGlyphBounds.x2 = gx2; previousGlyphBounds.y2 = gy2; return res; }
mlib_status __mlib_GraphicsDrawArc_AB_32( mlib_image *buffer, mlib_s16 x, mlib_s16 y, mlib_s32 r, mlib_f32 t1, mlib_f32 t2, mlib_s32 c, mlib_s32 a) { mlib_s32 stride = mlib_ImageGetStride(buffer) / sizeof (mlib_s32); mlib_s32 width = mlib_ImageGetWidth(buffer) - 1; mlib_s32 height = mlib_ImageGetHeight(buffer) - 1; mlib_s32 *data = mlib_ImageGetData(buffer); mlib_s32 *line0, *line; mlib_s32 cx, cy, del, mask; mlib_s32 sin1, cos1, sin2, cos2, oct1, oct2, flagc, flagd; pinfo buf0[BUFSIZE], *buf = 0; mlib_s32 count, scount; mlib_s32 start, end; mlib_s32 ind0, ind1, ind2, mdel, k; mlib_d64 c0, c1, c2; mlib_f32 cf; mlib_d64 d_one = ((mlib_d64 *)mlib_v_TabAlias)[0]; mlib_s32 a1; mlib_f32 fa; mlib_d64 da, da1, dc; mlib_f32 falpha = vis_to_float(0xFF000000); a &= 0xff; a1 = ~a & 0xff; fa = vis_to_float((a << 16) | (a << 8) | a); da = vis_to_double((a << 6), (a << 22) | (a << 6)); da1 = vis_to_double((a1 << 6), (a1 << 22) | (a1 << 6)); dc = vis_fmul8x16al(vis_to_float(c), vis_to_float(0x4000)); vis_write_gsr((1 << 3) + 0); c |= 0xFF000000; cf = vis_to_float(c); if (!data) return (MLIB_NULLPOINTER); if (r < 0) return (MLIB_FAILURE); CHECK_INTERSECTION; if (r == 0) { if (INSIDE(x, y)) BLE32((data + (stride * y + x)), 0); return (MLIB_SUCCESS); } if (mlib_fabs(t1 - t2) >= PIx2) return (__mlib_GraphicsDrawCircle_AB_32(buffer, x, y, r, c, a)); { mlib_f32 tt = t1; t1 = -t2; t2 = -tt; } if (t1 > t2) t2 += PIx2; line0 = data + stride * y + x; if (r > RADMAX) { buf = (pinfo *) __mlib_malloc(sizeof (pinfo) * r); if (!buf) return (MLIB_FAILURE); } else buf = buf0; k = (0x100000 / r); FILL_BUF; GET_BORDERS; FILL_FLAGS; FILL_CL_FLAGS; start = 0; end = count; PROC_OCT(y, y - height, x - width, x, 2, cos, 1, 2, stride, -1); start = 1; end = count; PROC_OCT(y, y - height, -x, width - x, 1, cos, 2, 1, stride, 1); start = 0; end = count; PROC_OCT(height - y, -y, x - width, x, 5, cos, 2, 1, -stride, -1); start = 1; end = count; PROC_OCT(height - y, -y, -x, width - x, 6, cos, 1, 2, -stride, 1); start = 1; end = scount; PROC_OCT(x, x - width, y - height, y, 3, sin, 2, 1, 1, -stride); start = 0; end = scount; PROC_OCT(x, x - width, -y, height - y, 4, sin, 1, 2, 1, stride); start = 1; end = scount; PROC_OCT(width - x, -x, y - height, y, 0, sin, 1, 2, -1, -stride); start = 0; end = scount; PROC_OCT(width - x, -x, -y, height - y, 7, sin, 2, 1, -1, stride); if (buf != buf0) __mlib_free(buf); return (MLIB_SUCCESS); }
void plP_plfclp(PLINT *x, PLINT *y, PLINT npts, PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax, void (*draw) (short *, short *, PLINT)) { PLINT i, x1, x2, y1, y2; int iclp = 0, iout = 2; short xclp[2*PL_MAXPOLY+2], yclp[2*PL_MAXPOLY+2]; int drawable; int crossed_xmin1 = 0, crossed_xmax1 = 0; int crossed_ymin1 = 0, crossed_ymax1 = 0; int crossed_xmin2 = 0, crossed_xmax2 = 0; int crossed_ymin2 = 0, crossed_ymax2 = 0; /* Must have at least 3 points and draw() specified */ if (npts < 3 || !draw) return; for (i = 0; i < npts - 1; i++) { x1 = x[i]; x2 = x[i+1]; y1 = y[i]; y2 = y[i+1]; drawable = (INSIDE(x1, y1) && INSIDE(x2, y2)); if ( ! drawable) drawable = ! clipline(&x1, &y1, &x2, &y2, xmin, xmax, ymin, ymax); if (!drawable) { /* Store the edges outside the viewport */ xclp[iout] = x2; yclp[iout] = y2; iout ++; } else { /* Boundary crossing condition -- coming in. */ crossed_xmin2 = (x1 == xmin); crossed_xmax2 = (x1 == xmax); crossed_ymin2 = (y1 == ymin); crossed_ymax2 = (y1 == ymax); iout = iclp+2; /* If the first segment, just add it. */ if (iclp == 0) { xclp[iclp] = x1; yclp[iclp] = y1; iclp++; xclp[iclp] = x2; yclp[iclp] = y2; iclp++; } /* Not first point. If first point of this segment matches up to the previous point, just add it. */ else if (x1 == xclp[iclp-1] && y1 == yclp[iclp-1]) { xclp[iclp] = x2; yclp[iclp] = y2; iclp++; } /* Otherwise, we need to add both points, to connect the points in the * polygon along the clip boundary. If we encircled a corner, we have * to add that first. */ else { /* Treat the case where we encircled two corners: Construct a polygon out of the subset of vertices Note that the direction is important too when adding the extra points */ xclp[iclp+1] = x2; yclp[iclp+1] = y2; xclp[iclp+2] = x1; yclp[iclp+2] = y1; iout = iout - iclp; /* Upper two */ if ( ((crossed_xmin1 && crossed_xmax2) || (crossed_xmin2 && crossed_xmax1)) && pointinpolygon(iout,&xclp[iclp+1],&yclp[iclp+1],xmin,ymax) ) { if ( crossed_xmin1 ) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } } /* Lower two */ else if ( ((crossed_xmin1 && crossed_xmax2) || (crossed_xmin2 && crossed_xmax1)) && pointinpolygon(iout,&xclp[iclp+1],&yclp[iclp+1],xmin,ymin) ) { if ( crossed_xmin1 ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } } /* Left two */ else if ( ((crossed_ymin1 && crossed_ymax2) || (crossed_ymin2 && crossed_ymax1)) && pointinpolygon(iout,&xclp[iclp+1],&yclp[iclp+1],xmin,ymin) ) { if ( crossed_ymin1 ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } } /* Right two */ else if ( ((crossed_ymin1 && crossed_ymax2) || (crossed_ymin2 && crossed_ymax1)) && pointinpolygon(iout,&xclp[iclp+1],&yclp[iclp+1],xmax,ymin) ) { if ( crossed_ymin1 ) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } } /* Now the case where we encircled one corner */ /* Lower left */ else if ( (crossed_xmin1 && crossed_ymin2) || (crossed_ymin1 && crossed_xmin2) ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } /* Lower right */ else if ( (crossed_xmax1 && crossed_ymin2) || (crossed_ymin1 && crossed_xmax2) ) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } /* Upper left */ else if ( (crossed_xmin1 && crossed_ymax2) || (crossed_ymax1 && crossed_xmin2) ) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } /* Upper right */ else if ( (crossed_xmax1 && crossed_ymax2) || (crossed_ymax1 && crossed_xmax2) ) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } /* Now add current segment. */ xclp[iclp] = x1; yclp[iclp] = y1; iclp++; xclp[iclp] = x2; yclp[iclp] = y2; iclp++; } /* Boundary crossing condition -- going out. */ crossed_xmin1 = (x2 == xmin); crossed_xmax1 = (x2 == xmax); crossed_ymin1 = (y2 == ymin); crossed_ymax1 = (y2 == ymax); } } /* Limit case - all vertices are outside of bounding box. So just fill entire box, *if* the bounding box is completely encircled. */ if (iclp == 0) { PLINT xmin1, xmax1, ymin1, ymax1; xmin1 = xmax1 = x[0]; ymin1 = ymax1 = y[0]; for (i = 1; i < npts; i++) { if (x[i] < xmin1) xmin1 = x[i]; if (x[i] > xmax1) xmax1 = x[i]; if (y[i] < ymin1) ymin1 = y[i]; if (y[i] > ymax1) ymax1 = y[i]; } if (xmin1 <= xmin && xmax1 >= xmax && ymin1 <= ymin && ymax1 >= ymax ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; (*draw)(xclp, yclp, iclp); return; } } /* Now handle cases where fill polygon intersects two sides of the box */ if (iclp >= 2) { int debug=0; int dir = circulation(x, y, npts); if (debug) { if ( (xclp[0] == xmin && xclp[iclp-1] == xmax) || (xclp[0] == xmax && xclp[iclp-1] == xmin) || (yclp[0] == ymin && yclp[iclp-1] == ymax) || (yclp[0] == ymax && yclp[iclp-1] == ymin) || (xclp[0] == xmin && yclp[iclp-1] == ymin) || (yclp[0] == ymin && xclp[iclp-1] == xmin) || (xclp[0] == xmax && yclp[iclp-1] == ymin) || (yclp[0] == ymin && xclp[iclp-1] == xmax) || (xclp[0] == xmax && yclp[iclp-1] == ymax) || (yclp[0] == ymax && xclp[iclp-1] == xmax) || (xclp[0] == xmin && yclp[iclp-1] == ymax) || (yclp[0] == ymax && xclp[iclp-1] == xmin) ) { printf("dir=%d, clipped points:\n", dir); for (i=0; i < iclp; i++) printf(" x[%d]=%d y[%d]=%d", i, xclp[i], i, yclp[i]); printf("\n"); printf("pre-clipped points:\n"); for (i=0; i < npts; i++) printf(" x[%d]=%d y[%d]=%d", i, x[i], i, y[i]); printf("\n"); } } /* The cases where the fill region is divided 2/2 */ /* Divided horizontally */ if (xclp[0] == xmin && xclp[iclp-1] == xmax) { if (dir > 0) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } } else if (xclp[0] == xmax && xclp[iclp-1] == xmin) { if (dir > 0) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } else { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } } /* Divided vertically */ else if (yclp[0] == ymin && yclp[iclp-1] == ymax) { if (dir > 0) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } else { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } } else if (yclp[0] == ymax && yclp[iclp-1] == ymin) { if (dir > 0) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } else { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } } /* The cases where the fill region is divided 3/1 -- LL LR UR UL +-----+ +-----+ +-----+ +-----+ | | | | | \| |/ | | | | | | | | | |\ | | /| | | | | +-----+ +-----+ +-----+ +-----+ Note when we go the long way around, if the direction is reversed the three vertices must be visited in the opposite order. */ /* LL, short way around */ else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir < 0) || (yclp[0] == ymin && xclp[iclp-1] == xmin && dir > 0) ) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } /* LL, long way around, counterclockwise */ else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir > 0)) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } /* LL, long way around, clockwise */ else if ((yclp[0] == ymin && xclp[iclp-1] == xmin && dir < 0)) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } /* LR, short way around */ else if ((xclp[0] == xmax && yclp[iclp-1] == ymin && dir > 0) || (yclp[0] == ymin && xclp[iclp-1] == xmax && dir < 0) ) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } /* LR, long way around, counterclockwise */ else if (yclp[0] == ymin && xclp[iclp-1] == xmax && dir > 0) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } /* LR, long way around, clockwise */ else if (xclp[0] == xmax && yclp[iclp-1] == ymin && dir < 0) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } /* UR, short way around */ else if ((xclp[0] == xmax && yclp[iclp-1] == ymax && dir < 0) || (yclp[0] == ymax && xclp[iclp-1] == xmax && dir > 0) ) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } /* UR, long way around, counterclockwise */ else if (xclp[0] == xmax && yclp[iclp-1] == ymax && dir > 0) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; } /* UR, long way around, clockwise */ else if (yclp[0] == ymax && xclp[iclp-1] == xmax && dir < 0) { xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } /* UL, short way around */ else if ((xclp[0] == xmin && yclp[iclp-1] == ymax && dir > 0) || (yclp[0] == ymax && xclp[iclp-1] == xmin && dir < 0) ) { xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; } /* UL, long way around, counterclockwise */ else if (yclp[0] == ymax && xclp[iclp-1] == xmin && dir > 0) { xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++; xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; } /* UL, long way around, clockwise */ else if (xclp[0] == xmin && yclp[iclp-1] == ymax && dir < 0) { xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++; xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++; } } /* Draw the sucker */ if (iclp >= 3) (*draw)(xclp, yclp, iclp); }