MgPath& MgPath::reverse() { if (getSubPathCount() > 1) { MgPath subpath; std::list<MgPath> paths; for (size_t i = 0; i < m_data->types.size(); i++) { if (m_data->types[i] == kMgMoveTo && subpath.getCount() > 0) { paths.push_back(subpath); subpath.clear(); } subpath.m_data->types.push_back(m_data->types[i]); subpath.m_data->points.push_back(m_data->points[i]); } if (subpath.getCount() > 0) { paths.push_back(subpath); } clear(); for (std::list<MgPath>::reverse_iterator it = paths.rbegin(); it != paths.rend(); ++it) { append(it->reverse()); } } else { for (int i = 0, j = getCount() - 1; i < j; i++, j--) { if (i > 0) { mgSwap(m_data->types[i], m_data->types[j]); } mgSwap(m_data->points[i], m_data->points[j]); } } return *this; }
bool GiCanvasGdi::drawImage(long hmWidth, long hmHeight, HBITMAP hbitmap, const Box2d& rectW, bool fast) { BOOL ret = FALSE; HDC hdc = m_draw->getDrawDC(); if (hdc != NULL && hmWidth > 0 && hmHeight > 0 && hbitmap != NULL && m_owner->getClipWorld().isIntersect(Box2d(rectW, true))) { RECT_2D clipBox; RECT rc, rcDraw, rcFrom; // rc: 整个图像对应的显示坐标区域 (rectW * xf().worldToDisplay()).get(rc); // rcDraw: 图像经剪裁后的可显示部分 Box2d(gs()->getClipBox(clipBox)).get(rcFrom); if (!IntersectRect(&rcDraw, &rc, &rcFrom)) return false; long width, height; // pixel units width = MulDiv(hmWidth, GetDeviceCaps(hdc, LOGPIXELSX), 2540); height = MulDiv(hmHeight, GetDeviceCaps(hdc, LOGPIXELSY), 2540); // rcFrom: rcDraw在原始图像上对应的图像范围 rcFrom.left = MulDiv(rcDraw.left - rc.left, width, rc.right - rc.left); rcFrom.top = MulDiv(rcDraw.top - rc.top, height, rc.bottom - rc.top); rcFrom.right = MulDiv(rcDraw.right - rc.left, width, rc.right - rc.left); rcFrom.bottom = MulDiv(rcDraw.bottom - rc.top, height, rc.bottom - rc.top); // 根据rectW正负决定是否颠倒显示图像 if (rectW.xmin > rectW.xmax) mgSwap(rcDraw.left, rcDraw.right); if (rectW.ymin > rectW.ymax) mgSwap(rcDraw.top, rcDraw.bottom); GiCompatibleDC memDC (hdc); if (memDC == NULL) return false; KGDIObject bmp (memDC, hbitmap, false); KGDIObject brush (hdc, ::GetStockObject(NULL_BRUSH), false); int nBltMode = (!fast || m_owner->isPrint()) ? HALFTONE : COLORONCOLOR; int nOldMode = ::SetStretchBltMode(hdc, nBltMode); ::SetBrushOrgEx(hdc, rcDraw.left % 8, rcDraw.top % 8, NULL); ret = ::StretchBlt(hdc, rcDraw.left, rcDraw.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, memDC, rcFrom.left, rcFrom.top, rcFrom.right - rcFrom.left, rcFrom.bottom - rcFrom.top, SRCCOPY); ::SetStretchBltMode(hdc, nOldMode); } return ret ? true : false; }
bool GiCanvasGdipImpl::drawImage(G::Bitmap* pBmp, const Box2d& rectW, bool fast) { RECT_2D rc, rcDraw, rcFrom; Box2d rect; float width = (float)pBmp->GetWidth(); float height = (float)pBmp->GetHeight(); // rc: 整个图像对应的显示坐标区域 (rectW * gs()->xf().worldToDisplay()).get(rc); // rcDraw: 图像经剪裁后的可显示部分 gs()->getClipBox(rcDraw); if (rect.intersectWith(Box2d(rc), Box2d(rcDraw)).isEmpty()) return false; rect.get(rcDraw); // rcFrom: rcDraw在原始图像上对应的图像范围 rcFrom.left = (rcDraw.left - rc.left) * width / (rc.right - rc.left); rcFrom.top = (rcDraw.top - rc.top) * height / (rc.bottom - rc.top); rcFrom.right = (rcDraw.right - rc.left) * width / (rc.right - rc.left); rcFrom.bottom = (rcDraw.bottom - rc.top) * height / (rc.bottom - rc.top); // 根据rectW正负决定是否颠倒显示图像 if (rectW.xmin > rectW.xmax) mgSwap(rcDraw.left, rcDraw.right); if (rectW.ymin > rectW.ymax) mgSwap(rcDraw.top, rcDraw.bottom); G::InterpolationMode nOldMode = getDrawGs()->GetInterpolationMode(); getDrawGs()->SetInterpolationMode( (!fast || gs()->isPrint()) ? G::InterpolationModeBilinear : G::InterpolationModeLowQuality); G::Status ret = getDrawGs()->DrawImage(pBmp, G::RectF(rcDraw.left, rcDraw.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top), rcFrom.left, rcFrom.top, rcFrom.right - rcFrom.left, rcFrom.bottom - rcFrom.top, G::UnitPixel); getDrawGs()->SetInterpolationMode(nOldMode); return G::Ok == ret; }
void GiTransform::setViewScaleRange(float minScale, float maxScale) { if (minScale > maxScale) mgSwap(minScale, maxScale); minScale = mgMax(minScale, 1e-5f); minScale = mgMin(minScale, 0.5f); maxScale = mgMax(maxScale, 1.f); maxScale = mgMin(maxScale, 50.f); m_impl->minViewScale = minScale; m_impl->maxViewScale = maxScale; }
int mgcurv::arcToBezier( Point2d points[16], const Point2d& center, float rx, float ry, float startAngle, float sweepAngle) { if (mgIsZero(rx) || fabsf(sweepAngle) < 1e-5) return 0; if (mgIsZero(ry)) ry = rx; if (sweepAngle > _M_2PI) sweepAngle = _M_2PI; else if (sweepAngle < -_M_2PI) sweepAngle = -_M_2PI; int n = 0; if (fabsf(sweepAngle) < _M_PI_2 + 1e-5) { _arcToBezier(points, center, rx, ry, startAngle, sweepAngle); n = 4; } else if (sweepAngle > 0) { startAngle = mgbase::to0_2PI(startAngle); n = _arcToBezierPlusSweep( points, center, rx, ry, startAngle, sweepAngle); } else // sweepAngle < 0 { float endAngle = startAngle + sweepAngle; sweepAngle = -sweepAngle; startAngle = mgbase::to0_2PI(endAngle); n = _arcToBezierPlusSweep( points, center, rx, ry, startAngle, sweepAngle); for (int i = 0; i < n / 2; i++) mgSwap(points[i], points[n - 1 - i]); } return n; }
bool MgArc::_reverse() { mgSwap(_points[1], _points[2]); return true; }