static void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc) { RegLocation rlResult; rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); newLIR2(cUnit, kThumb2Vnegd, S2D(rlResult.lowReg, rlResult.highReg), S2D(rlSrc.lowReg, rlSrc.highReg)); storeValueWide(cUnit, rlDest, rlResult); }
static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) { bool isDouble; int defaultResult; bool ltNaNBias; RegLocation rlResult; switch(mir->dalvikInsn.opCode) { case OP_CMPL_FLOAT: isDouble = false; defaultResult = -1; break; case OP_CMPG_FLOAT: isDouble = false; defaultResult = 1; break; case OP_CMPL_DOUBLE: isDouble = true; defaultResult = -1; break; case OP_CMPG_DOUBLE: isDouble = true; defaultResult = 1; break; default: return true; } if (isDouble) { rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); dvmCompilerClobberSReg(cUnit, rlDest.sRegLow); rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true); loadConstant(cUnit, rlResult.lowReg, defaultResult); newLIR2(cUnit, kThumb2Vcmpd, S2D(rlSrc1.lowReg, r1Src2.highReg), S2D(rlSrc2.lowReg, rlSrc2.highReg)); } else { rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); dvmCompilerClobberSReg(cUnit, rlDest.sRegLow); rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true); loadConstant(cUnit, rlResult.lowReg, defaultResult); newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg); } assert(!FPREG(rlResult.lowReg)); newLIR0(cUnit, kThumb2Fmstat); genIT(cUnit, (defaultResult == -1) ? kArmCondGt : kArmCondMi, ""); newLIR2(cUnit, kThumb2MovImmShift, rlResult.lowReg, modifiedImmediate(-defaultResult)); // Must not alter ccodes genIT(cUnit, kArmCondEq, ""); loadConstant(cUnit, rlResult.lowReg, 0); storeValue(cUnit, rlDest, rlResult); return false; }
static bool genInlinedAbsDouble(CompilationUnit *cUnit, MIR *mir) { RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1); RegLocation rlDest = inlinedTargetWide(cUnit, mir, true); rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); newLIR2(cUnit, kThumb2Vabsd, S2D(rlResult.lowReg, rlResult.highReg), S2D(rlSrc.lowReg, rlSrc.highReg)); storeValueWide(cUnit, rlDest, rlResult); return false; }
bool GiGraphics::drawBeeline(const GiContext* ctx, const Point2d& startPt, const Point2d& endPt, bool modelUnit) { Vector2d vec((endPt - startPt) * RAYMUL); Point2d pts[2] = { (startPt - vec) * S2D(xf(), modelUnit), (endPt + vec) * S2D(xf(), modelUnit) }; if (!mglnrel::clipLine(pts[0], pts[1], m_impl->rectDraw)) return false; return rawLine(ctx, pts[0].x, pts[0].y, pts[1].x, pts[1].y); }
bool GiGraphics::drawLine(const GiContext* ctx, const Point2d& startPt, const Point2d& endPt, bool modelUnit) { if (!DRAW_RECT(m_impl, modelUnit).isIntersect(Box2d(startPt, endPt))) return false; Point2d pts[2] = { startPt * S2D(xf(), modelUnit), endPt * S2D(xf(), modelUnit) }; if (!mglnrel::clipLine(pts[0], pts[1], m_impl->rectDraw)) return false; return rawLine(ctx, pts[0].x, pts[0].y, pts[1].x, pts[1].y); }
void print_ut(int all, const struct utmp *u) { int lu, ll; #ifdef HAVE_STRUCT_UTMP_UT_ID int lid; #endif #ifdef HAVE_STRUCT_UTMP_UT_PID int lpid; #endif #ifdef PTY_UTMP_E_EXIT int let, lee; #endif #ifdef HAVE_STRUCT_UTMP_UT_TYPE if (!all && ((u->ut_type == EMPTY) || (u->ut_type == DEAD_PROCESS))) return; #endif lu = sizeof(u->ut_name); ll = sizeof(u->ut_line); printf("%-*.*s:", lu, lu, u->ut_name); printf("%-*.*s:", ll, ll, u->ut_line); #ifdef HAVE_STRUCT_UTMP_UT_ID lid = sizeof(u->ut_id); printf("%-*.*s:", lid, lid, u->ut_id); #endif #ifdef HAVE_STRUCT_UTMP_UT_PID lpid = S2D(u->ut_pid); printf("%*ld", lpid, (long)u->ut_pid); #endif #ifdef PTY_UTMP_E_EXIT let = S2D(u->ut_exit.PTY_UTMP_E_TERMINATION); lee = S2D(u->ut_exit.PTY_UTMP_E_EXIT); printf("(%*ld,", let, (long)u->ut_exit.PTY_UTMP_E_TERMINATION); printf("%*ld)", lee, (long)u->ut_exit.PTY_UTMP_E_EXIT); #endif #ifdef HAVE_STRUCT_UTMP_UT_TYPE printf(" %-9s", ut_typename(u->ut_type)); #endif printf(" %s", ctime(&u->ut_time) + 4); #ifdef HAVE_STRUCT_UTMP_UT_HOST if (u->ut_host[0]) printf(" %.*s\n", (int) sizeof(u->ut_host), u->ut_host); #endif return; }
bool GiGraphics::drawHermiteSplines(const GiContext* ctx, int count, const Point2d* knots, const Vector2d* knotvs, bool closed, bool modelUnit) { if (count < 2 || !knots || !knotvs || isStopping()) return false; count = mgMin(count, 0x1000); int i; Point2d pt; Vector2d vec; vector<Point2d> pxpoints; Matrix2d matD(S2D(xf(), modelUnit)); Matrix2d mat2(matD / 3.f); pxpoints.resize(1 + (closed ? count : count - 1) * 3); Point2d *pxs = &pxpoints.front(); pt = knots[0] * matD; // 第一个Bezier段的起点 vec = knotvs[0] * mat2; // 第一个Bezier段的起始矢量 *pxs++ = pt; // 产生Bezier段的起点 for (i = 1; i < count; i++) { // 计算每一个Bezier段 *pxs++ = (pt += vec); // 产生Bezier段的第二点 pt = knots[i] * matD; // Bezier段的终点 vec = knotvs[i] * mat2; // Bezier段的终止矢量 *pxs++ = pt - vec; // 产生Bezier段的第三点 *pxs++ = pt; // 产生Bezier段的终点 } if (closed) { *pxs++ = (pt += vec); // 产生Bezier段的第二点 *pxs++ = 2 * pxpoints[0] - pxpoints[1].asVector(); // 产生Bezier段的第三点 *pxs++ = pxpoints[0]; // 产生Bezier段的终点 } return rawBeziers(ctx, &pxpoints.front(), getSize(pxpoints), closed); }
bool GiGraphics::drawEllipse(const GiContext* ctx, const Point2d& center, float rx, float ry, bool modelUnit) { if (rx < _MGZERO || isStopping()) return false; bool ret = false; Matrix2d matD(S2D(xf(), modelUnit)); if (ry < _MGZERO) { ry = (Vector2d(rx, rx) * matD).x; ry = fabsf((Vector2d(ry, ry) * matD.inverse()).y); } const Box2d extent (center, rx*2.f, ry*2.f); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (mgIsZero(matD.m12) && mgIsZero(matD.m21)) { Point2d cen (center * matD); rx *= fabsf(matD.m11); ry *= fabsf(matD.m22); ret = rawEllipse(ctx, cen.x - rx, cen.y - ry, 2 * rx, 2 * ry); } else { Point2d pxs[13]; mgcurv::ellipseToBezier(pxs, center, rx, ry); matD.transformPoints(13, pxs); ret = rawBeziers(ctx, pxs, 13, true); } return ret; }
bool GiGraphics::drawSplines(const GiContext* ctx, int count, const Point2d* knots, const Vector2d* knotvs, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 2 || knots == NULL || knotvs == NULL) return false; GiLock lock (&m_impl->drawRefcnt); count = mgMin(count, static_cast<int>(1 + (0x2000 - 1) / 3)); int i; Point2d pt; Vector2d vec; vector<Point2d> pxpoints; Matrix2d matD(S2D(xf(), modelUnit)); // 开辟整形像素坐标数组 pxpoints.resize(1 + (count - 1) * 3); Point2d *pxs = &pxpoints.front(); pt = knots[0] * matD; // 第一个Bezier段的起点 vec = knotvs[0] * matD / 3.f; // 第一个Bezier段的起始矢量 *pxs++ = pt; // 产生Bezier段的起点 for (i = 1; i < count; i++) // 计算每一个Bezier段 { *pxs++ = (pt += vec); // 产生Bezier段的第二点 pt = knots[i] * matD; // Bezier段的终点 vec = knotvs[i] * matD / 3.f; // Bezier段的终止矢量 *pxs++ = pt - vec; // 产生Bezier段的第三点 *pxs++ = pt; // 产生Bezier段的终点 } // 绘图 return rawBeziers(ctx, &pxpoints.front(), getSize(pxpoints)); }
bool GiGraphics::drawPath(const GiContext* ctx, int count, const Point2d* points, const UInt8* types, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 2 || points == NULL || types == NULL) return false; GiLock lock (&m_impl->drawRefcnt); if (count > 0x2000) count = 0x2000; Matrix2d matD(S2D(xf(), modelUnit)); const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; vector<Point2d> pxpoints; pxpoints.resize(count); Point2d *pxs = &pxpoints.front(); for (int i = 0; i < count; i++) pxs[i] = points[i] * matD; return rawPath(ctx, count, pxs, types); }
static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) { int op = kThumbBkpt; RegLocation rlResult; switch (mir->dalvikInsn.opcode) { case OP_ADD_DOUBLE_2ADDR: case OP_ADD_DOUBLE: op = kThumb2Vaddd; break; case OP_SUB_DOUBLE_2ADDR: case OP_SUB_DOUBLE: op = kThumb2Vsubd; break; case OP_DIV_DOUBLE_2ADDR: case OP_DIV_DOUBLE: op = kThumb2Vdivd; break; case OP_MUL_DOUBLE_2ADDR: case OP_MUL_DOUBLE: op = kThumb2Vmuld; break; case OP_REM_DOUBLE_2ADDR: case OP_REM_DOUBLE: case OP_NEG_DOUBLE: { return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2); } default: return true; } rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); assert(rlSrc1.wide); rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); assert(rlSrc2.wide); rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); assert(rlDest.wide); assert(rlResult.wide); newLIR3(cUnit, (ArmOpcode)op, S2D(rlResult.lowReg, rlResult.highReg), S2D(rlSrc1.lowReg, rlSrc1.highReg), S2D(rlSrc2.lowReg, rlSrc2.highReg)); storeValueWide(cUnit, rlDest, rlResult); return false; }
bool GiGraphics::drawPath(const GiContext* ctx, const MgPath& path, bool fill, bool modelUnit) { if (ctx && ctx->hasArrayHead() && path.getSubPathCount() == 1 && !path.isClosed()) { MgPath pathw(path); GiContext ctx2(*ctx); pathw.transform(S2D(xf(), modelUnit)); ctx2.setNoFillColor(); ctx2.setStartArrayHead(0); ctx2.setEndArrayHead(0); return drawPathWithArrayHead(ctx2, pathw, ctx->getStartArrayHead(), ctx->getEndArrayHead()); } return drawPath_(ctx, path, fill, S2D(xf(), modelUnit)); }
bool GiGraphics::drawHandle(const Point2d& pnt, int type, float angle, bool modelUnit) { if (m_impl->canvas && type >= 0 && !m_impl->stopping && !pnt.isDegenerate()) { Point2d ptd(pnt * S2D(xf(), modelUnit)); return m_impl->canvas->drawHandle(ptd.x, ptd.y, type, angle); } return false; }
bool GiGraphics::drawClosedBSplines(const GiContext* ctx, int count, const Point2d* ctlpts, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 3 || ctlpts == NULL) return false; GiLock lock (&m_impl->drawRefcnt); count = mgMin(count, static_cast<int>((0x2000 - 1) / 3)); const Box2d extent (count, ctlpts); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; int i; Point2d pt1, pt2, pt3, pt4; float d6 = 1.f / 6.f; vector<Point2d> pxpoints; Matrix2d matD(S2D(xf(), modelUnit)); // 开辟整形像素坐标数组 pxpoints.resize(1 + count * 3); Point2d *pxs = &pxpoints.front(); // 计算第一个曲线段 pt1 = ctlpts[0] * matD; pt2 = ctlpts[1] * matD; pt3 = ctlpts[2] * matD; pt4 = ctlpts[3 % count] * matD; (*pxs++).set((pt1.x + 4 * pt2.x + pt3.x)*d6, (pt1.y + 4 * pt2.y + pt3.y)*d6); (*pxs++).set((4 * pt2.x + 2 * pt3.x) *d6, (4 * pt2.y + 2 * pt3.y) *d6); (*pxs++).set((2 * pt2.x + 4 * pt3.x) *d6, (2 * pt2.y + 4 * pt3.y) *d6); (*pxs++).set((pt2.x + 4 * pt3.x + pt4.x)*d6, (pt2.y + 4 * pt3.y + pt4.y)*d6); // 计算其余曲线段 for (i = 4; i < count + 3; i++) { pt1 = pt2; pt2 = pt3; pt3 = pt4; pt4 = ctlpts[i % count] * matD; (*pxs++).set((4 * pt2.x + 2 * pt3.x) *d6, (4 * pt2.y + 2 * pt3.y) *d6); (*pxs++).set((2 * pt2.x + 4 * pt3.x) *d6, (2 * pt2.y + 4 * pt3.y) *d6); (*pxs++).set((pt2.x + 4 * pt3.x + pt4.x)*d6, (pt2.y + 4 * pt3.y + pt4.y)*d6); } // 绘图 bool ret = rawBeginPath(); if (ret) { ret = rawMoveTo(pxs[0].x, pxs[0].y); ret = rawBezierTo(pxs + 1, getSize(pxpoints) - 1); ret = rawClosePath(); ret = rawEndPath(ctx, true); } return ret; }
bool GiGraphics::drawHandle(const Point2d& pnt, int type, bool modelUnit) { if (m_impl->canvas && type >= 0 && !m_impl->stopping) { Point2d ptd(pnt * S2D(xf(), modelUnit)); m_impl->canvas->drawHandle(ptd.x, ptd.y, type); return true; } return false; }
bool GiGraphics::drawBeziers(const GiContext* ctx, int count, const Point2d* points, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 4 || points == NULL) return false; GiLock lock (&m_impl->drawRefcnt); if (count > 0x2000) count = 0x2000; count = 1 + (count - 1) / 3 * 3; bool ret = false; vector<Point2d> pxpoints; vector<Point2d> pointBuf; int i, j, n, si, ei; Point2d * pxs; Matrix2d matD(S2D(xf(), modelUnit)); const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) // 全部在显示区域内 { pxpoints.resize(count); pxs = &pxpoints.front(); for (i = 0; i < count; i++) pxs[i] = points[i] * matD; ret = rawBeziers(ctx, pxs, count); } else { pointBuf.resize(count); for (i = 0; i < count; i++) // 转换到像素坐标 pointBuf[i] = points[i] * matD; Point2d* pts = &pointBuf.front(); si = ei = 0; for (i = 3; i < count; i += 3) { for ( ; i < count && m_impl->rectDraw.isIntersect(Box2d(4, &pts[ei])); i += 3) ei = i; n = ei - si + 1; if (n > 1) { pxpoints.resize(n); pxs = &pxpoints.front(); for (j=0; j<n; j++) pxs[j] = pts[si + j]; ret = rawBeziers(ctx, pxs, n); } si = ei = i; } } return ret; }
bool GiGraphics::drawBeziers(const GiContext* ctx, int count, const Point2d* points, bool closed, bool modelUnit) { if (count < 4 || !points || isStopping()) return false; if (count > 0x2000) count = 0x2000; count = 1 + (count - 1) / 3 * 3; bool ret = false; vector<Point2d> pxpoints; vector<Point2d> pointBuf; int i, j, n, si, ei; Point2d * pxs; Matrix2d matD(S2D(xf(), modelUnit)); const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (closed) { pxpoints.resize(count); pxs = &pxpoints.front(); for (i = 0; i < count; i++) pxs[i] = points[i] * matD; ret = rawBeziers(ctx, pxs, count, closed); } else if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) { // 全部在显示区域内 pxpoints.resize(count); pxs = &pxpoints.front(); for (i = 0; i < count; i++) pxs[i] = points[i] * matD; ret = rawBeziers(ctx, pxs, count); } else { pointBuf.resize(count); for (i = 0; i < count; i++) // 转换到像素坐标 pointBuf[i] = points[i] * matD; Point2d* pts = &pointBuf.front(); for (i = 0; i + 3 < count;) { for (; i + 3 < count && !m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3) ; si = ei = i; for (; i + 3 < count && m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3) ei = i + 3; if (ei > si) { n = ei - si + 1; pxpoints.resize(n); pxs = &pxpoints.front(); for (j=0; j<n; j++) pxs[j] = pts[si + j]; ret = rawBeziers(ctx, pxs, n); } } } return ret; }
bool GiGraphics::drawLines(const GiContext* ctx, int count, const Point2d* points, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 2 || points == NULL) return false; if (count > 0x2000) count = 0x2000; GiLock lock (&m_impl->drawRefcnt); int i; Point2d pt1, pt2, ptLast; vector<Point2d> pxpoints; vector<Point2d> pointBuf; bool ret = false; Matrix2d matD(S2D(xf(), modelUnit)); const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) // 全部在显示区域内 { pxpoints.resize(count); Point2d* pxs = &pxpoints.front(); int n = 0; for (i = 0; i < count; i++) { pt2 = points[i] * matD; if (i == 0 || fabs(pt1.x - pt2.x) > 2 || fabs(pt1.y - pt2.y) > 2) { pt1 = pt2; pxs[n++] = pt2; } } ret = rawLines(ctx, pxs, n); } else // 部分在显示区域内 { pointBuf.resize(count); for (i = 0; i < count; i++) // 转换到像素坐标 pointBuf[i] = points[i] * matD; Point2d* pts = &pointBuf.front(); ptLast = pts[0]; PolylineAux aux(this, ctx); for (i = 0; i < count - 1; i++) { ret = DrawEdge(count, i, pts, ptLast, aux, m_impl->rectDraw) || ret; } } return ret; }
static bool genInlineSqrt(CompilationUnit *cUnit, MIR *mir) { ArmLIR *branch; RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1); RegLocation rlDest = inlinedTargetWide(cUnit, mir, true); rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); newLIR2(cUnit, kThumb2Vsqrtd, S2D(rlResult.lowReg, rlResult.highReg), S2D(rlSrc.lowReg, rlSrc.highReg)); newLIR2(cUnit, kThumb2Vcmpd, S2D(rlResult.lowReg, rlResult.highReg), S2D(rlResult.lowReg, rlResult.highReg)); newLIR0(cUnit, kThumb2Fmstat); branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq); dvmCompilerClobberCallRegs(cUnit); LOAD_FUNC_ADDR(cUnit, r2, (int) (double (*)(double)) sqrt); newLIR3(cUnit, kThumb2Fmrrd, r0, r1, S2D(rlSrc.lowReg, rlSrc.highReg)); newLIR1(cUnit, kThumbBlxR, r2); newLIR3(cUnit, kThumb2Fmdrr, S2D(rlResult.lowReg, rlResult.highReg), r0, r1); ArmLIR *label = newLIR0(cUnit, kArmPseudoTargetLabel); label->defMask = ENCODE_ALL; branch->generic.target = (LIR *)label; storeValueWide(cUnit, rlDest, rlResult); return false; }
bool GiGraphics::drawRoundRect(const GiContext* ctx, const Box2d& rect, float rx, float ry, bool modelUnit) { if (m_impl->drawRefcnt == 0 || rect.isEmpty()) return false; GiLock lock (&m_impl->drawRefcnt); bool ret = false; if (ry < _MGZERO) ry = rx; if (!DRAW_RECT(m_impl, modelUnit).isIntersect(rect)) // 全部在显示区域外 return false; if (rx < _MGZERO) { Point2d points[4] = { rect.leftBottom(), rect.rightBottom(), rect.rightTop(), rect.leftTop() }; return drawPolygon(ctx, 4, points); } else { Point2d points[16]; mgRoundRectToBeziers(points, rect, rx, ry); S2D(xf(), modelUnit).TransformPoints(16, points); ret = rawBeginPath(); if (ret) { ret = rawMoveTo(points[0].x, points[0].y); ret = rawBezierTo(&points[1], 3); ret = rawLineTo(points[4].x, points[4].y); ret = rawBezierTo(&points[5], 3); ret = rawLineTo(points[8].x, points[8].y); ret = rawBezierTo(&points[9], 3); ret = rawLineTo(points[12].x, points[12].y); ret = rawBezierTo(&points[13], 3); ret = rawClosePath(); ret = rawEndPath(ctx, true); } } return ret; }
bool GiGraphics::drawPie(const GiContext* ctx, const Point2d& center, float rx, float ry, float startAngle, float sweepAngle, bool modelUnit) { if (m_impl->drawRefcnt == 0 || rx < _MGZERO || fabsf(sweepAngle) < 1e-5f) return false; GiLock lock (&m_impl->drawRefcnt); if (ry < _MGZERO) ry = rx; const Box2d extent (center, rx*2.f, ry*2.f); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; Point2d pxs[16]; int count = mgcurv::arcToBezier(pxs, center, rx, ry, startAngle, sweepAngle); if (count < 4) return false; S2D(xf(), modelUnit).TransformPoints(count, pxs); Point2d cen(center * S2D(xf(), modelUnit)); bool ret = rawBeginPath(); if (ret) { rawMoveTo(cen.x, cen.y); rawLineTo(pxs[0].x, pxs[0].y); for (int i = 1; i + 2 < count; i += 3) { rawBezierTo(pxs[i].x, pxs[i].y, pxs[i+1].x, pxs[i+1].y, pxs[i+2].x, pxs[i+2].y); } rawClosePath(); ret = rawEndPath(ctx, true); } return ret; }
bool GiGraphics::drawClosedSplines(const GiContext* ctx, int count, const Point2d* knots, const Vector2d* knotvs, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 2 || knots == NULL || knotvs == NULL) return false; GiLock lock (&m_impl->drawRefcnt); count = mgMin(count, static_cast<int>((0x2000 - 1) / 3)); int i, j = 0; Point2d pt; Vector2d vec; vector<Point2d> pxpoints; Matrix2d matD(S2D(xf(), modelUnit)); // 开辟像素坐标数组 pxpoints.resize(1 + count * 3); Point2d *pxs = &pxpoints.front(); pt = knots[0] * matD; // 第一个Bezier段的起点 vec = knotvs[0] * matD / 3.f; // 第一个Bezier段的起始矢量 pxs[j++] = pt; // 产生Bezier段的起点 for (i = 1; i < count; i++) // 计算每一个Bezier段 { pxs[j++] = (pt += vec); // 产生Bezier段的第二点 pt = knots[i] * matD; // Bezier段的终点 vec = knotvs[i] * matD / 3.f; // Bezier段的终止矢量 pxs[j++] = pt - vec; // 产生Bezier段的第三点 pxs[j++] = pt; // 产生Bezier段的终点 } pxs[j++] = (pt += vec); // 产生Bezier段的第二点 pxs[j] = 2 * pxs[0] - pxs[1].asVector(); // 产生Bezier段的第三点 pxs[j+1] = pxs[0]; // 产生Bezier段的终点 // 绘图 bool ret = rawBeginPath(); if (ret) { rawMoveTo(pxs[0].x, pxs[0].y); for (i = 1; i + 2 < getSize(pxpoints); i += 3) { rawBezierTo(pxs[i].x, pxs[i].y, pxs[i+1].x, pxs[i+1].y, pxs[i+2].x, pxs[i+2].y); } rawClosePath(); ret = rawEndPath(ctx, true); } return ret; }
bool GiGraphics::drawBSplines(const GiContext* ctx, int count, const Point2d* ctlpts, bool closed, bool modelUnit) { if (closed) { if (count < 3 || !ctlpts || isStopping()) return false; count = mgMin(count, static_cast<int>((0x2000 - 1) / 3)); } else { if (count < 4 || !ctlpts || isStopping()) return false; count = mgMin(count, static_cast<int>(3 + (0x2000 - 1) / 3)); } const Box2d extent (count, ctlpts); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; int i; Point2d pt1, pt2, pt3, pt4; float d6 = 1.f / 6.f; vector<Point2d> pxpoints; Matrix2d matD(S2D(xf(), modelUnit)); // 开辟像素坐标数组 pxpoints.resize(1 + (closed ? count : (count - 3)) * 3); Point2d *pxs = &pxpoints.front(); // 计算第一个曲线段 pt1 = ctlpts[0] * matD; pt2 = ctlpts[1] * matD; pt3 = ctlpts[2] * matD; pt4 = ctlpts[3 % count] * matD; (*pxs++).set((pt1.x + 4 * pt2.x + pt3.x)*d6, (pt1.y + 4 * pt2.y + pt3.y)*d6); (*pxs++).set((4 * pt2.x + 2 * pt3.x) *d6, (4 * pt2.y + 2 * pt3.y) *d6); (*pxs++).set((2 * pt2.x + 4 * pt3.x) *d6, (2 * pt2.y + 4 * pt3.y) *d6); (*pxs++).set((pt2.x + 4 * pt3.x + pt4.x)*d6, (pt2.y + 4 * pt3.y + pt4.y)*d6); // 计算其余曲线段 for (i = 4; i < (closed ? (count + 3) : count); i++) { pt1 = pt2; pt2 = pt3; pt3 = pt4; pt4 = ctlpts[i % count] * matD; (*pxs++).set((4 * pt2.x + 2 * pt3.x) *d6, (4 * pt2.y + 2 * pt3.y) *d6); (*pxs++).set((2 * pt2.x + 4 * pt3.x) *d6, (2 * pt2.y + 4 * pt3.y) *d6); (*pxs++).set((pt2.x + 4 * pt3.x + pt4.x)*d6,(pt2.y + 4 * pt3.y + pt4.y)*d6); } // 绘图 return rawBeziers(ctx, &pxpoints.front(), getSize(pxpoints), closed); }
void print_utx(int all, const struct utmpx *u) { int lu, ll, lid, lpid; #ifdef PTY_UTMPX_E_EXIT int let, lee; #endif if (!all && ((u->ut_type == EMPTY) || (u->ut_type == DEAD_PROCESS))) return; lu = sizeof(u->ut_user); ll = sizeof(u->ut_line); lid = sizeof(u->ut_id); printf("%-*.*s:", lu, lu, u->ut_user); printf("%-*.*s:", ll, ll, u->ut_line); printf("%-*.*s", lid, lid, u->ut_id); if (lu + ll + lid >= 60) printf("\n"); else printf(":"); lpid = S2D(u->ut_pid); printf("%*ld", lpid, (long)u->ut_pid); #ifdef PTY_UTMPX_E_EXIT let = S2D(u->ut_exit.PTY_UTMPX_E_TERMINATION); lee = S2D(u->ut_exit.PTY_UTMPX_E_EXIT); printf("(%*ld,", let, (long)u->ut_exit.PTY_UTMPX_E_TERMINATION); printf("%*ld)", lee, (long)u->ut_exit.PTY_UTMPX_E_EXIT); #endif printf(" %-9s", ut_typename(u->ut_type)); printf(" %s", ctime(&u->ut_tv.tv_sec) + 4); #ifdef HAVE_STRUCT_UTMPX_UT_HOST if (u->ut_host[0]) printf(" %s\n", u->ut_host); #endif return; }
bool GiGraphics::drawRoundRect(const GiContext* ctx, const Box2d& rect, float rx, float ry, bool modelUnit) { if (rect.isEmpty() || isStopping()) return false; bool ret = false; if (ry < _MGZERO) ry = rx; if (!DRAW_RECT(m_impl, modelUnit).isIntersect(rect)) // 全部在显示区域外 return false; if (rx < _MGZERO) { Point2d points[4] = { rect.leftBottom(), rect.rightBottom(), rect.rightTop(), rect.leftTop() }; return drawPolygon(ctx, 4, points); } else { Point2d pxs[16]; mgcurv::roundRectToBeziers(pxs, rect, rx, ry); S2D(xf(), modelUnit).transformPoints(16, pxs); ret = rawBeginPath(); if (ret) { rawMoveTo(pxs[0].x, pxs[0].y); rawBezierTo(pxs[1].x, pxs[1].y, pxs[2].x, pxs[2].y, pxs[3].x, pxs[3].y); rawLineTo(pxs[4].x, pxs[4].y); rawBezierTo(pxs[5].x, pxs[5].y, pxs[6].x, pxs[6].y, pxs[7].x, pxs[7].y); rawLineTo(pxs[8].x, pxs[8].y); rawBezierTo(pxs[9].x, pxs[9].y, pxs[10].x, pxs[10].y, pxs[11].x, pxs[11].y); rawLineTo(pxs[12].x, pxs[12].y); rawBezierTo(pxs[13].x, pxs[13].y, pxs[14].x, pxs[14].y, pxs[15].x, pxs[15].y); rawClosePath(); ret = rawEndPath(ctx, true); } } return ret; }
bool GiGraphics::drawEllipse(const GiContext* ctx, const Point2d& center, float rx, float ry, bool modelUnit) { if (m_impl->drawRefcnt == 0 || rx < _MGZERO) return false; GiLock lock (&m_impl->drawRefcnt); bool ret = false; Matrix2d matD(S2D(xf(), modelUnit)); if (ry < _MGZERO) { ry = (Vector2d(rx, rx) * matD).x; ry = fabsf((Vector2d(ry, ry) * matD.inverse()).y); } const Box2d extent (center, rx*2.f, ry*2.f); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (mgIsZero(matD.m12) && mgIsZero(matD.m21)) { Point2d cen (center * matD); rx *= fabsf(matD.m11); ry *= fabsf(matD.m22); ret = rawEllipse(ctx, cen.x - rx, cen.y - ry, 2 * rx, 2 * ry); } else { Point2d pxs[13]; mgcurv::ellipseToBezier(pxs, center, rx, ry); matD.TransformPoints(13, pxs); ret = rawBeginPath(); if (ret) { rawMoveTo(pxs[0].x, pxs[0].y); for (int i = 1; i + 2 < 13; i += 3) { rawBezierTo(pxs[i].x, pxs[i].y, pxs[i+1].x, pxs[i+1].y, pxs[i+2].x, pxs[i+2].y); } rawClosePath(); ret = rawEndPath(ctx, true); } } return ret; }
bool GiGraphics::drawPolygon(const GiContext* ctx, int count, const Point2d* points, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 2 || points == NULL) return false; GiLock lock (&m_impl->drawRefcnt); if (count > 0x2000) count = 0x2000; bool ret = false; const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) // 全部在显示区域内 { ret = _DrawPolygon(m_impl->canvas, ctx, count, points, true, true, true, modelUnit); } else // 部分在显示区域内 { PolygonClip clip (m_impl->rectDraw); if (!clip.clip(count, points, &S2D(xf(), modelUnit))) // 多边形剪裁 return false; count = clip.getCount(); points = clip.getPoints(); ret = _DrawPolygon(m_impl->canvas, ctx, count, points, false, true, false, modelUnit); int ienter = findInvisibleEdge(clip); if (ienter == count) { ret = _DrawPolygon(m_impl->canvas, ctx, count, points, false, false, true, modelUnit) || ret; } else { ret = drawPolygonEdge(PolylineAux(this, ctx), count, clip, ienter) || ret; } } return ret; }
bool GiGraphics::drawPath(const GiContext* ctx, const GiPath& path, bool fill, bool modelUnit) { int n = path.getCount(); if (n == 0) return false; Matrix2d matD(S2D(xf(), modelUnit)); const Point2d* pts = path.getPoints(); const char* types = path.getTypes(); Point2d a, b, c; rawBeginPath(); for (int i = 0; i < n; i++) { switch (types[i] & ~kGiCloseFigure) { case kGiMoveTo: a = pts[i] * matD; rawMoveTo(a.x, a.y); break; case kGiLineTo: a = pts[i] * matD; rawLineTo(a.x, a.y); break; case kGiBeziersTo: if (i + 2 >= n) return false; a = pts[i] * matD; b = pts[i+1] * matD; c = pts[i+2] * matD; rawBezierTo(a.x, a.y, b.x, b.y, c.x, c.y); i += 2; break; default: return false; } if (types[i] & kGiCloseFigure) rawClosePath(); } return rawEndPath(ctx, fill); }
bool GiGraphics::drawEllipse(const GiContext* ctx, const Point2d& center, float rx, float ry, bool modelUnit) { if (m_impl->drawRefcnt == 0 || rx < _MGZERO) return false; GiLock lock (&m_impl->drawRefcnt); bool ret = false; Matrix2d matD(S2D(xf(), modelUnit)); if (ry < _MGZERO) ry = rx; const Box2d extent (center, rx*2.f, ry*2.f); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (mgIsZero(matD.m12) && mgIsZero(matD.m21)) { Point2d cen (center * matD); rx *= matD.m11; ry *= matD.m22; ret = rawEllipse(ctx, cen.x - rx, cen.y - ry, 2 * rx, 2 * ry); } else { Point2d points[13]; mgEllipseToBezier(points, center, rx, ry); matD.TransformPoints(13, points); ret = rawBeginPath(); if (ret) { ret = rawMoveTo(points[0].x, points[0].y); ret = rawBezierTo(points + 1, 12); ret = rawClosePath(); ret = rawEndPath(ctx, true); } } return ret; }
bool GiGraphics::_drawPolygon(const GiContext* ctx, int count, const Point2d* points, bool m2d, bool fill, bool edge, bool modelUnit) { GiContext context (ctx ? *ctx : m_impl->ctx); if (!edge) context.setNullLine(); if (!fill) context.setNoFillColor(); if (context.isNullLine() && !context.hasFillColor()) return false; vector<Point2d> pxpoints; Point2d pt1, pt2; Matrix2d matD(S2D(xf(), modelUnit)); pxpoints.resize(count); Point2d *pxs = &pxpoints.front(); int n = 0; for (int i = 0; i < count; i++) { pt2 = points[i]; if (m2d) pt2 *= matD; if (i == 0 || count <= 4 || fabsf(pt1.x - pt2.x) > 2 || fabsf(pt1.y - pt2.y) > 2) { pt1 = pt2; pxs[n++] = pt1; } } if (n == 4 && m2d && mgEquals(pxs[0].x, pxs[3].x) && mgEquals(pxs[1].x, pxs[2].x) && mgEquals(pxs[0].y, pxs[1].y) && mgEquals(pxs[2].y, pxs[3].y)) { Box2d rc(pxs[0].x, pxs[0].y, pxs[2].x, pxs[2].y, true); return rawRect(&context, rc.xmin, rc.ymin, rc.width(), rc.height()); } return rawPolygon(&context, pxs, n); }