?? miarc.c
字號(hào):
d = Vr * sqrt(d); Z = N + cbrt(t + d) + cbrt(t - d); flip = 0; } A = sqrt((Z + Z) - Nk); T = (Fk - Z) * K / A; inx = 0.0; solution = FALSE; b = -A + K; d = b * b - 4 * (Z + T); if (d >= 0) { d = sqrt(d); y = (b + d) / 2; if ((y >= 0.0) && (y < hepp)) { solution = TRUE; if (y > hepm) y = h; t = y / h; x = w * sqrt(1 - (t * t)); t = K - y; if (rs - (t * t) >= 0) t = sqrt(rs - (t * t)); else t = 0; if (flip == 2) inx = x - t; else outx = x + t; } } b = A + K; d = b * b - 4 * (Z - T); /* Because of the large magnitudes involved, we lose enough precision * that sometimes we end up with a negative value near the axis, when * it should be positive. This is a workaround. */ if (d < 0 && !solution) d = 0.0; if (d >= 0) { d = sqrt(d); y = (b + d) / 2; if (y < hepp) { if (y > hepm) y = h; t = y / h; x = w * sqrt(1 - (t * t)); t = K - y; if (rs - (t * t) >= 0) inx = x - sqrt(rs - (t * t)); else inx = x; } y = (b - d) / 2; if (y >= 0.0) { if (y > hepm) y = h; t = y / h; x = w * sqrt(1 - (t * t)); t = K - y; if (rs - (t * t) >= 0) t = sqrt(rs - (t * t)); else t = 0; if (flip == 1) inx = x - t; else outx = x + t; } } span->lx = ICEIL(xorg - outx); if (inx <= 0.0) { spdata->count1++; span->lw = ICEIL(xorg + outx) - span->lx; span->rx = ICEIL(xorg + inx); span->rw = -ICEIL(xorg - inx); } else { spdata->count2++; span->lw = ICEIL(xorg - inx) - span->lx; span->rx = ICEIL(xorg + inx); span->rw = ICEIL(xorg + outx) - span->rx; } span++; } if (spdata->bot) { outx = w + r; if (r >= h && r <= w) inx = 0.0; else if (Nk < 0.0 && -Nk < Hs) { inx = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk); if (inx > w - r) inx = w - r; } else inx = w - r; span->lx = ICEIL(xorg - outx); if (inx <= 0.0) { span->lw = ICEIL(xorg + outx) - span->lx; span->rx = ICEIL(xorg + inx); span->rw = -ICEIL(xorg - inx); } else { span->lw = ICEIL(xorg - inx) - span->lx; span->rx = ICEIL(xorg + inx); span->rw = ICEIL(xorg + outx) - span->rx; } } if (spdata->hole) { span = &spdata->spans[spdata->count1]; span->lw = -span->lx; span->rx = 1; span->rw = span->lw; spdata->count1--; spdata->count2++; }}static doubletailX(double K, struct arc_def *def, struct arc_bound *bounds, struct accelerators *acc){ double w, h, r; double Hs, Hf, WH, Vk, Nk, Fk, Vr, N, Nc, Z, rs; double A, T, b, d, x, y, t, hepp, hepm; int flip, solution; double xs[2]; double *xp; w = def->w; h = def->h; r = def->l; rs = r * r; Hs = acc->h2; WH = -acc->h2mw2; Nk = def->w * r; Vk = (Nk * Hs) / (WH + WH); Hf = acc->h4; Nk = (Hf - Nk * Nk) / WH; if (K == 0.0) { if (Nk < 0.0 && -Nk < Hs) { xs[0] = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk); xs[1] = w - r; if (acc->left.valid && boundedLe(K, bounds->left) && !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0) return xs[1]; if (acc->right.valid && boundedLe(K, bounds->right) && !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0) return xs[1]; return xs[0]; } return w - r; } Fk = Hf / WH; hepp = h + EPSILON; hepm = h - EPSILON; N = (K * K + Nk) / 6.0; Nc = N * N * N; Vr = Vk * K; xp = xs; xs[0] = 0.0; t = Nc + Vr * Vr; d = Nc + t; if (d < 0.0) { d = Nc; b = N; if ( (b < 0.0) == (t < 0.0) ) { b = -b; d = -d; } Z = N - 2.0 * b * cos(acos(-t / d) / 3.0); if ( (Z < 0.0) == (Vr < 0.0) ) flip = 2; else flip = 1; } else { d = Vr * sqrt(d); Z = N + cbrt(t + d) + cbrt(t - d); flip = 0; } A = sqrt((Z + Z) - Nk); T = (Fk - Z) * K / A; solution = FALSE; b = -A + K; d = b * b - 4 * (Z + T); if (d >= 0 && flip == 2) { d = sqrt(d); y = (b + d) / 2; if ((y >= 0.0) && (y < hepp)) { solution = TRUE; if (y > hepm) y = h; t = y / h; x = w * sqrt(1 - (t * t)); t = K - y; if (rs - (t * t) >= 0) t = sqrt(rs - (t * t)); else t = 0; *xp++ = x - t; } } b = A + K; d = b * b - 4 * (Z - T); /* Because of the large magnitudes involved, we lose enough precision * that sometimes we end up with a negative value near the axis, when * it should be positive. This is a workaround. */ if (d < 0 && !solution) d = 0.0; if (d >= 0) { d = sqrt(d); y = (b + d) / 2; if (y < hepp) { if (y > hepm) y = h; t = y / h; x = w * sqrt(1 - (t * t)); t = K - y; if (rs - (t * t) >= 0) *xp++ = x - sqrt(rs - (t * t)); else *xp++ = x; } y = (b - d) / 2; if (y >= 0.0 && flip == 1) { if (y > hepm) y = h; t = y / h; x = w * sqrt(1 - (t * t)); t = K - y; if (rs - (t * t) >= 0) t = sqrt(rs - (t * t)); else t = 0; *xp++ = x - t; } } if (xp > &xs[1]) { if (acc->left.valid && boundedLe(K, bounds->left) && !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0) return xs[1]; if (acc->right.valid && boundedLe(K, bounds->right) && !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0) return xs[1]; } return xs[0];}static miArcSpanData *miComputeWideEllipse(int lw, miArc *parc, gboolean *mustFree){ register miArcSpanData *spdata; register arcCacheRec *cent, *lruent; register int k; arcCacheRec fakeent; if (!lw) lw = 1; if (parc->height <= 1500) { *mustFree = FALSE; cent = lastCacheHit; if (cent->lw == lw && cent->width == parc->width && cent->height == parc->height) { cent->lrustamp = ++lrustamp; return cent->spdata; } lruent = &arcCache[0]; for (k = CACHESIZE, cent = lruent; --k >= 0; cent++) { if (cent->lw == lw && cent->width == parc->width && cent->height == parc->height) { cent->lrustamp = ++lrustamp; lastCacheHit = cent; return cent->spdata; } if (cent->lrustamp < lruent->lrustamp) lruent = cent; }#if 0 if (!cacheType) { cacheType = CreateNewResourceType(miFreeArcCache); (void) AddResource(FakeClientID(0), cacheType, NULL); }#endif } else { lruent = &fakeent; lruent->spdata = NULL; *mustFree = TRUE; } k = (parc->height >> 1) + ((lw - 1) >> 1); spdata = lruent->spdata; if (!spdata || spdata->k != k) { if (spdata) g_free(spdata); spdata = (miArcSpanData *)g_malloc(sizeof(miArcSpanData) + sizeof(miArcSpan) * (k + 2)); lruent->spdata = spdata; if (!spdata) { lruent->lrustamp = 0; lruent->lw = 0; return spdata; } spdata->spans = (miArcSpan *)(spdata + 1); spdata->k = k; } spdata->top = !(lw & 1) && !(parc->width & 1); spdata->bot = !(parc->height & 1); lruent->lrustamp = ++lrustamp; lruent->lw = lw; lruent->width = parc->width; lruent->height = parc->height; if (lruent != &fakeent) lastCacheHit = lruent; if (parc->width == parc->height) miComputeCircleSpans(lw, parc, spdata); else miComputeEllipseSpans(lw, parc, spdata); return spdata;}static voidmiFillWideEllipse(GdkDrawable *pDraw, GdkGC *pGC, miArc *parc){ GdkSpan* points; register GdkSpan* pts; miArcSpanData *spdata; gboolean mustFree; register miArcSpan *span; register int xorg, yorgu, yorgl; register int n; yorgu = parc->height + GDK_GC_FBDATA(pGC)->values.line_width; points = ALLOCATE_LOCAL(sizeof(GdkSpan) * yorgu * 2); spdata = miComputeWideEllipse(GDK_GC_FBDATA(pGC)->values.line_width, parc, &mustFree); if (!spdata) { DEALLOCATE_LOCAL(points); return; } pts = points; span = spdata->spans; xorg = parc->x + (parc->width >> 1); yorgu = parc->y + (parc->height >> 1); yorgl = yorgu + (parc->height & 1); yorgu -= spdata->k; yorgl += spdata->k; if (spdata->top) { pts->x = xorg; pts->y = yorgu - 1; pts->width = 1; pts++; span++; } for (n = spdata->count1; --n >= 0; ) { pts[0].x = xorg + span->lx; pts[0].y = yorgu; pts[0].width = span->lw; pts[1] = pts[0]; pts[1].y = yorgl; yorgu++; yorgl--; pts += 2; span++; } if (spdata->hole) { pts[0].x = xorg; pts[0].y = yorgl; pts[0].width = 1; pts++; } for (n = spdata->count2; --n >= 0; ) { pts[0].x = xorg + span->lx; pts[0].y = yorgu; pts[0].width = span->lw; pts[1].x = xorg + span->rx; pts[1].y = pts[0].y; pts[1].width = span->rw; pts[2].x = pts[0].x; pts[2].y = yorgl; pts[2].width = pts[0].width; pts[3].x = pts[1].x; pts[3].y = pts[2].y; pts[3].width = pts[1].width; yorgu++; yorgl--; pts += 4; span++; } if (spdata->bot) { if (span->rw <= 0) { pts[0].x = xorg + span->lx; pts[0].y = yorgu; pts[0].width = span->lw; pts++; } else { pts[0].x = xorg + span->lx; pts[0].y = yorgu; pts[0].width = span->lw; pts[1].x = xorg + span->rx; pts[1].y = pts[0].y; pts[1].width = span->rw; pts += 2; } } if (mustFree) g_free(spdata); gdk_fb_fill_spans(pDraw, pGC, points, pts - points, FALSE); DEALLOCATE_LOCAL(points);}/* * miPolyArc strategy: * * If arc is zero width and solid, we don't have to worry about the rasterop * or join styles. For wide solid circles, we use a fast integer algorithm. * For wide solid ellipses, we use special case floating point code. * Otherwise, we set up pDrawTo and pGCTo according to the rasterop, then * draw using pGCTo and pDrawTo. If the raster-op was "tricky," that is, * if it involves the destination, then we use PushPixels to move the bits * from the scratch drawable to pDraw. (See the wide line code for a * fuller explanation of this.) */voidmiPolyArc(GdkDrawable *pDraw, GdkGC *pGC, int narcs, miArc *parcs){ register int i; miArc *parc; int xMin, xMax, yMin, yMax; int pixmapWidth = 0, pixmapHeight = 0; int xOrg = 0, yOrg = 0; int width; gboolean fTricky; GdkDrawable* pDrawTo; GdkColor fg, bg; GdkGC* pGCTo; miPolyArcPtr polyArcs; int cap[2], join[2]; int iphase; int halfWidth; GdkGCValues gcv; width = GDK_GC_FBDATA(pGC)->values.line_width; if(width == 0 && GDK_GC_FBDATA(pGC)->values.line_style == GDK_LINE_SOLID) { for(i = narcs, parc = parcs; --i >= 0; parc++) miArcSegment( pDraw, pGC, *parc, (miArcFacePtr) 0, (miArcFacePtr) 0 ); fillSpans (pDraw, pGC); } else { if ((GDK_GC_FBDATA(pGC)->values.line_style == GDK_LINE_SOLID) && narcs) { while (parcs->width && parcs->height && (parcs->angle2 >= FULLCIRCLE || parcs->angle2 <= -FULLCIRCLE)) { miFillWideEllipse(pDraw, pGC, parcs); if (!--narcs) return; parcs++; } } /* Set up pDrawTo and pGCTo based on the rasterop */ switch(GDK_GC_FBDATA(pGC)->alu) { case GDK_CLEAR: /* 0 */ case GDK_COPY: /* src */ case GDK_COPY_INVERT: /* NOT src */ case GDK_SET: /* 1 */ fTricky = FALSE; pDrawTo = pDraw; pGCTo = pGC; break; default: fTricky = TRUE; /* find bounding box around arcs */ xMin = yMin = SHRT_MAX; xMax = yMax = SHRT_MIN; for(i = narcs, parc = parcs; --i >= 0; parc++) { xMin = MIN (xMin, parc->x);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -