void tft_t::rectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t c) { if (!h || !w) return; uint16_t yt, bMask; if (!transform()) goto disp; if (!portrait()) { swap(x, y); swap(w, h); } yt = vsTransformBack(y); if ((int16_t)yt < (int16_t)topEdge() && \ (int16_t)(yt + h) >= (int16_t)topEdge()) { // Top edge clipping h -= topEdge() - yt; y = upperEdge(); yt = vsTransformBack(y); } else if (yt < bottomEdge() && yt + h >= bottomEdge()) // Bottom edge clipping h = bottomEdge() - yt; if (y + h > bottomEdge()) // Transform edge split if (y < bottomEdge()) { if (!portrait()) { rectangle(y, x, bottomEdge() - y, w, c); rectangle(topEdge(), x, h - (bottomEdge() - y), w, c); } else { rectangle(x, y, w, bottomEdge() - y, c); rectangle(x, topEdge(), w, h - (bottomEdge() - y), c); } return; } if (yt < topMask()) { if (yt + h < topMask()) return; h -= topMask() - yt; y = vsTransform(topMask()); } bMask = vsMaximum() - bottomMask(); if (yt >= bMask) return; if (yt + h > bMask) h -= yt + h - bMask; if (!portrait()) { area(y, x, h, w); goto draw; } disp: area(x, y, w, h); draw: start(); while (h--) for (uint16_t xx = 0; xx < w; xx++) write16(c); }
uint16_t tft_t::vsTransformBack(uint16_t y) const { #ifndef NO_CHECK if ((int16_t)y < 0) return y; #endif if (y < topEdge() || y >= bottomEdge()) return y; if (y < upperEdge()) y += vsHeight(); y -= upperEdge(); // Relative to upperEdge y += topEdge(); // Relative to 0 return y; }
uint16_t tft_t::vsTransform(uint16_t y) const { #ifndef NO_CHECK if ((int16_t)y < 0) return y; #endif if (y < topEdge() || y >= bottomEdge()) return y; y -= topEdge(); // Relative to upperEdge y += upperEdge(); // Relative to 0 if (y >= bottomEdge()) // Transform edge y -= vsHeight(); return y; }
Size Transformation::getCropSize(vector<Point2f> areaCorners, Size targetSize) { // Figure out the approximate width/height of the license plate region, so we can maintain the aspect ratio. LineSegment leftEdge(round(areaCorners[3].x), round(areaCorners[3].y), round(areaCorners[0].x), round(areaCorners[0].y)); LineSegment rightEdge(round(areaCorners[2].x), round(areaCorners[2].y), round(areaCorners[1].x), round(areaCorners[1].y)); LineSegment topEdge(round(areaCorners[0].x), round(areaCorners[0].y), round(areaCorners[1].x), round(areaCorners[1].y)); LineSegment bottomEdge(round(areaCorners[3].x), round(areaCorners[3].y), round(areaCorners[2].x), round(areaCorners[2].y)); float w = distanceBetweenPoints(leftEdge.midpoint(), rightEdge.midpoint()); float h = distanceBetweenPoints(bottomEdge.midpoint(), topEdge.midpoint()); float aspect = w/h; int width = targetSize.width; int height = round(((float) width) / aspect); if (height > targetSize.height) { height = targetSize.height; width = round(((float) height) * aspect); } return Size(width, height); }
// ------------------------------------------------------------------ // Coordinates: // row and column are square coordinates. // sr and sc are display coordinates void Viewer::drawGrid() { GridChar gc; GridChar::LineType rowType; GridChar::LineType colType; for (int sr = 0; sr < height; ++sr) { // Classify row type if (topEdge(sr)) rowType = GridChar::edge1; else if (botEdge(sr)) rowType = GridChar::edge2; else if (majorRow(sr)) rowType = GridChar::major; else if (minorRow(sr)) rowType = GridChar::minor; else rowType = GridChar::none; for (int sc = 0; sc < width; ++sc) { // Classify col type if (leftEdge(sc)) colType = GridChar::edge1; else if (rightEdge(sc)) colType = GridChar::edge2; else if (majorCol(sc)) colType = GridChar::major; else if (minorCol(sc)) colType = GridChar::minor; else colType = GridChar::none; cv->setPixel(sr, sc, gc.boxGlyph(rowType, colType)); } } }
gint getMetric(Metric wm) { const int frameBorder(Style::instance().settings().frameBorder()); const bool narrowSpacing(false); // TODO: false -> read configuration const bool compositingActive(false); // TODO: implement check for this const bool hideTitleBar(false); // TODO: implement switch (wm) { case BorderLeft: case BorderRight: case BorderBottom: { gint border(0); // for now we think that respectWindowState is always true, // and WM will remove borders for maximized windows by default // TODO: impelement respectWindowState if( wm==BorderBottom && frameBorder >= QtSettings::BorderNoSide ) { // for tiny border, the convention is to have a larger bottom area in order to // make resizing easier border = std::max(frameBorder,4); } else if( frameBorder < QtSettings::BorderTiny ) { border = 0; } else if( compositingActive && frameBorder == QtSettings::BorderTiny ) { border = std::max( frameBorder, 3 ); } else { border = frameBorder; } return border; } case BorderTop: { gint topEdge(0); if( frameBorder == QtSettings::BorderNone && hideTitleBar ) { topEdge=0; } else { topEdge=3; // TFRAMESIZE } return Style::instance().settings().buttonSize()+topEdge; } case ButtonSpacing: { return ( narrowSpacing ? 1 : 3 ); } case ButtonMarginTop: case ButtonMarginBottom: { return 0; } case ShadowLeft: case ShadowRight: case ShadowTop: case ShadowBottom: { WindowShadow shadow(Style::instance().settings(), Style::instance().helper()); return int(shadow.shadowSize()-4); } default: { // -1 means we don't understand the query return -1; } } }
ViewerGL::Implementation::WipePolygonEnum ViewerGL::Implementation::getWipePolygon(const RectD & texRectClipped, QPolygonF & polygonPoints, bool rightPlane) const { ///Compute a second point on the plane separator line ///we don't really care how far it is from the center point, it just has to be on the line QPointF firstPoint, secondPoint; QPointF center; double angle; { QMutexLocker l(&wipeControlsMutex); center = wipeCenter; angle = wipeAngle; } ///extrapolate the line to the maximum size of the RoD so we're sure the line ///intersection algorithm works double maxSize = std::max(texRectClipped.x2 - texRectClipped.x1, texRectClipped.y2 - texRectClipped.y1) * 10000.; double xmax, ymax; xmax = std::cos(angle + M_PI_2) * maxSize; ymax = std::sin(angle + M_PI_2) * maxSize; firstPoint.setX(center.x() - xmax); firstPoint.setY(center.y() - ymax); secondPoint.setX(center.x() + xmax); secondPoint.setY(center.y() + ymax); QLineF inter(firstPoint, secondPoint); QLineF::IntersectType intersectionTypes[4]; QPointF intersections[4]; QLineF topEdge(texRectClipped.x1, texRectClipped.y2, texRectClipped.x2, texRectClipped.y2); QLineF rightEdge(texRectClipped.x2, texRectClipped.y2, texRectClipped.x2, texRectClipped.y1); QLineF bottomEdge(texRectClipped.x2, texRectClipped.y1, texRectClipped.x1, texRectClipped.y1); QLineF leftEdge(texRectClipped.x1, texRectClipped.y1, texRectClipped.x1, texRectClipped.y2); bool crossingTop = false, crossingRight = false, crossingLeft = false, crossingBtm = false; int validIntersectionsIndex[4]; validIntersectionsIndex[0] = validIntersectionsIndex[1] = -1; int numIntersec = 0; intersectionTypes[0] = inter.intersect(topEdge, &intersections[0]); if (intersectionTypes[0] == QLineF::BoundedIntersection) { validIntersectionsIndex[numIntersec] = 0; crossingTop = true; ++numIntersec; } intersectionTypes[1] = inter.intersect(rightEdge, &intersections[1]); if (intersectionTypes[1] == QLineF::BoundedIntersection) { validIntersectionsIndex[numIntersec] = 1; crossingRight = true; ++numIntersec; } intersectionTypes[2] = inter.intersect(bottomEdge, &intersections[2]); if (intersectionTypes[2] == QLineF::BoundedIntersection) { validIntersectionsIndex[numIntersec] = 2; crossingBtm = true; ++numIntersec; } intersectionTypes[3] = inter.intersect(leftEdge, &intersections[3]); if (intersectionTypes[3] == QLineF::BoundedIntersection) { validIntersectionsIndex[numIntersec] = 3; crossingLeft = true; ++numIntersec; } if ( (numIntersec != 0) && (numIntersec != 2) ) { ///Don't bother drawing the polygon, it is most certainly not visible in this case return ViewerGL::Implementation::eWipePolygonEmpty; } ///determine the orientation of the planes double crossProd = ( secondPoint.x() - center.x() ) * ( texRectClipped.y1 - center.y() ) - ( secondPoint.y() - center.y() ) * ( texRectClipped.x1 - center.x() ); if (numIntersec == 0) { ///the bottom left corner is on the left plane if ( (crossProd > 0) && ( (center.x() >= texRectClipped.x2) || (center.y() >= texRectClipped.y2) ) ) { ///the plane is invisible because the wipe handle is below or on the left of the texRectClipped return rightPlane ? ViewerGL::Implementation::eWipePolygonEmpty : ViewerGL::Implementation::eWipePolygonFull; } ///otherwise we draw the entire texture as usual return rightPlane ? ViewerGL::Implementation::eWipePolygonFull : ViewerGL::Implementation::eWipePolygonEmpty; } else { ///we have 2 intersects assert(validIntersectionsIndex[0] != -1 && validIntersectionsIndex[1] != -1); bool isBottomLeftOnLeftPlane = crossProd > 0; ///there are 6 cases if (crossingBtm && crossingLeft) { if ( (isBottomLeftOnLeftPlane && rightPlane) || (!isBottomLeftOnLeftPlane && !rightPlane) ) { //btm intersect is the first polygonPoints.insert(0, intersections[validIntersectionsIndex[0]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[1]]); polygonPoints.insert( 2, QPointF(texRectClipped.x1, texRectClipped.y2) ); polygonPoints.insert( 3, QPointF(texRectClipped.x2, texRectClipped.y2) ); polygonPoints.insert( 4, QPointF(texRectClipped.x2, texRectClipped.y1) ); polygonPoints.insert(5, intersections[validIntersectionsIndex[0]]); } else { polygonPoints.insert(0, intersections[validIntersectionsIndex[0]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[1]]); polygonPoints.insert( 2, QPointF(texRectClipped.x1, texRectClipped.y1) ); polygonPoints.insert(3, intersections[validIntersectionsIndex[0]]); } } else if (crossingBtm && crossingTop) { if ( (isBottomLeftOnLeftPlane && rightPlane) || (!isBottomLeftOnLeftPlane && !rightPlane) ) { ///btm intersect is the second polygonPoints.insert(0, intersections[validIntersectionsIndex[1]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[0]]); polygonPoints.insert( 2, QPointF(texRectClipped.x2, texRectClipped.y2) ); polygonPoints.insert( 3, QPointF(texRectClipped.x2, texRectClipped.y1) ); polygonPoints.insert(4, intersections[validIntersectionsIndex[1]]); } else { polygonPoints.insert(0, intersections[validIntersectionsIndex[1]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[0]]); polygonPoints.insert( 2, QPointF(texRectClipped.x1, texRectClipped.y2) ); polygonPoints.insert( 3, QPointF(texRectClipped.x1, texRectClipped.y1) ); polygonPoints.insert(4, intersections[validIntersectionsIndex[1]]); } } else if (crossingBtm && crossingRight) { if ( (isBottomLeftOnLeftPlane && rightPlane) || (!isBottomLeftOnLeftPlane && !rightPlane) ) { ///btm intersect is the second polygonPoints.insert(0, intersections[validIntersectionsIndex[1]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[0]]); polygonPoints.insert( 2, QPointF(texRectClipped.x2, texRectClipped.y1) ); polygonPoints.insert(3, intersections[validIntersectionsIndex[1]]); } else { polygonPoints.insert(0, intersections[validIntersectionsIndex[1]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[0]]); polygonPoints.insert( 2, QPointF(texRectClipped.x2, texRectClipped.y2) ); polygonPoints.insert( 3, QPointF(texRectClipped.x1, texRectClipped.y2) ); polygonPoints.insert( 4, QPointF(texRectClipped.x1, texRectClipped.y1) ); polygonPoints.insert(5, intersections[validIntersectionsIndex[1]]); } } else if (crossingLeft && crossingTop) { if ( (isBottomLeftOnLeftPlane && rightPlane) || (!isBottomLeftOnLeftPlane && !rightPlane) ) { ///left intersect is the second polygonPoints.insert(0, intersections[validIntersectionsIndex[1]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[0]]); polygonPoints.insert( 2, QPointF(texRectClipped.x1, texRectClipped.y2) ); polygonPoints.insert(3, intersections[validIntersectionsIndex[1]]); } else { polygonPoints.insert(0, intersections[validIntersectionsIndex[1]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[0]]); polygonPoints.insert( 2, QPointF(texRectClipped.x2, texRectClipped.y2) ); polygonPoints.insert( 3, QPointF(texRectClipped.x2, texRectClipped.y1) ); polygonPoints.insert( 4, QPointF(texRectClipped.x1, texRectClipped.y1) ); polygonPoints.insert(5, intersections[validIntersectionsIndex[1]]); } } else if (crossingLeft && crossingRight) { if ( (isBottomLeftOnLeftPlane && rightPlane) || (!isBottomLeftOnLeftPlane && !rightPlane) ) { ///left intersect is the second polygonPoints.insert(0, intersections[validIntersectionsIndex[1]]); polygonPoints.insert( 1, QPointF(texRectClipped.x1, texRectClipped.y2) ); polygonPoints.insert( 2, QPointF(texRectClipped.x2, texRectClipped.y2) ); polygonPoints.insert(3, intersections[validIntersectionsIndex[0]]); polygonPoints.insert(4, intersections[validIntersectionsIndex[1]]); } else { polygonPoints.insert(0, intersections[validIntersectionsIndex[1]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[0]]); polygonPoints.insert( 2, QPointF(texRectClipped.x2, texRectClipped.y1) ); polygonPoints.insert( 3, QPointF(texRectClipped.x1, texRectClipped.y1) ); polygonPoints.insert(4, intersections[validIntersectionsIndex[1]]); } } else if (crossingTop && crossingRight) { if ( (isBottomLeftOnLeftPlane && rightPlane) || (!isBottomLeftOnLeftPlane && !rightPlane) ) { ///right is second polygonPoints.insert(0, intersections[validIntersectionsIndex[0]]); polygonPoints.insert( 1, QPointF(texRectClipped.x2, texRectClipped.y2) ); polygonPoints.insert(2, intersections[validIntersectionsIndex[1]]); polygonPoints.insert(3, intersections[validIntersectionsIndex[0]]); } else { polygonPoints.insert(0, intersections[validIntersectionsIndex[0]]); polygonPoints.insert(1, intersections[validIntersectionsIndex[1]]); polygonPoints.insert( 2, QPointF(texRectClipped.x2, texRectClipped.y1) ); polygonPoints.insert( 3, QPointF(texRectClipped.x1, texRectClipped.y1) ); polygonPoints.insert( 4, QPointF(texRectClipped.x1, texRectClipped.y2) ); polygonPoints.insert(5, intersections[validIntersectionsIndex[0]]); } } else { assert(false); } } return ViewerGL::Implementation::eWipePolygonPartial; } // getWipePolygon
void tft_t::putch(char ch) { #ifndef NO_CHECK if ((int16_t)x() >= (int16_t)width() || (int16_t)y() >= (int16_t)height()) return; #endif if ((int16_t)(x() + FONT_WIDTH * zoom()) < 0) return; uint8_t h = FONT_HEIGHT * zoom(), w = FONT_WIDTH * zoom(); // Display coordinate, start coordinate uint16_t xx = x(), x0 = x(); uint16_t yy = y(), y0 = y(); uint8_t xStart = 0, xStop = w; uint8_t yStart = 0, yStop = h; #if 1 if (transform()) { if (!portrait()) { yy = xx; y0 = x0; yStop = xStop; swap(w, h); } uint16_t yt = vsTransformBack(yy); if ((int16_t)yt < (int16_t)topEdge() && \ (int16_t)(yt + h) >= (int16_t)topEdge()) { // Top edge clipping yStart = topEdge() - yt; yy = upperEdge(); y0 = yy - yStart; yt = vsTransformBack(yy); } else if (yt < bottomEdge() && yt + h >= bottomEdge()) // Bottom edge clipping yStop = bottomEdge() - yt; if (yt < topMask()) { if (yt + yStop - yStart < topMask()) return; yy = vsTransform(topMask()); yStart += topMask() - yt; y0 = yy - yStart; } uint16_t bMask = vsMaximum() - bottomMask(); if (yt >= bMask) return; if (yt + yStop - yStart > bMask) yStop -= yt + yStop - yStart - bMask; if (!portrait()) { swap(w, h); xx = yy; x0 = y0; xStart = yStart; xStop = yStop; yy = y(); y0 = y(); yStart = 0; yStop = h; } } #else if (transform()) { uint16_t xt = vsTransformBack(xx); if ((int16_t)xt < (int16_t)topEdge() && \ (int16_t)(xt + w) >= (int16_t)topEdge()) { // Top edge clipping xStart = topEdge() - xt; xx = upperEdge(); x0 = xx - xStart; xt = vsTransformBack(xx); } else if (xt < bottomEdge() && xt + w >= bottomEdge()) // Bottom edge clipping xStop = bottomEdge() - xt; if (xt < topMask()) { if (xt + xStop - xStart < topMask()) return; xx = vsTransform(topMask()); xStart += topMask() - xt; x0 = xx - xStart; } uint16_t bMask = vsMaximum() - bottomMask(); if (xt >= bMask) return; if (xt + xStop - xStart > bMask) xStop -= xt + xStop - xStart - bMask; } #endif bool xTransform = transform() && !portrait() && x0 < bottomEdge() && x0 + xStop - xStart > bottomEdge(); bool yTransform = transform() && portrait() && y0 < bottomEdge() && y0 + yStop - yStart > bottomEdge(); uint8_t xEnd = xTransform ? bottomEdge() - xx : xStop; draw: area(xx, yy, xEnd - xStart, h); start(); for (uint8_t i = yStart; i < yStop; i++) { if (yTransform && y0 + i == bottomEdge()) { area(x(), topEdge(), w, h); start(); yTransform = false; } unsigned char c; c = pgm_read_byte(&(ascii[ch - ' '][i / zoom()])) << (xStart / zoom()); for (uint8_t j = xStart; j < xEnd; j++) { if (c & 0x80) write16(foreground()); else write16(background()); if (j % zoom() == zoom() - 1) c <<= 1; } } if (xTransform) { xx = topEdge(); xStart = xEnd; xEnd = xStop; xTransform = false; goto draw; } }
std::list< CNCPoint > CDrilling::DrillBitVertices( const CNCPoint & origin, const double radius, const double length ) const { std::list<CNCPoint> top, spiral, bottom, countersink, result; double flutePitch = 5.0; // 5mm of depth per spiral of the drill bit's flute. double countersinkDepth = -1 * radius * tan(31.0); // this is the depth of the countersink cone at the end of the drill bit. (for a typical 118 degree bevel) unsigned int numPoints = 20; // number of points in one circle (360 degrees) i.e. how smooth do we want the graphics const double pi = 3.1415926; double alpha = 2 * pi / numPoints; // Get a circle at the top of the dill bit's path top = PointsAround( origin, radius, numPoints ); top.push_back( *(top.begin()) ); // Close the circle double depthPerItteration; countersinkDepth = -1 * radius * tan(31.0); // For a typical (118 degree bevel on the drill bit tip) unsigned int l_iNumItterations = numPoints * (length / flutePitch); depthPerItteration = (length - countersinkDepth) / l_iNumItterations; // Now generate the spirals. unsigned int i = 0; while( i++ < l_iNumItterations ) { double theta = alpha * i; CNCPoint pointOnCircle( cos( theta ) * radius, sin( theta ) * radius, 0 ); pointOnCircle += origin; // And spiral down as we go. pointOnCircle.SetZ( pointOnCircle.Z() - (depthPerItteration * i) ); spiral.push_back(pointOnCircle); } // End while // And now the countersink at the bottom of the drill bit. i = 0; while( i++ < numPoints ) { double theta = alpha * i; CNCPoint topEdge( cos( theta ) * radius, sin( theta ) * radius, 0 ); // This is at the top edge of the countersink topEdge.SetX( topEdge.X() + origin.X() ); topEdge.SetY( topEdge.Y() + origin.Y() ); topEdge.SetZ( origin.Z() - (length - countersinkDepth) ); spiral.push_back(topEdge); // And now at the very point of the countersink CNCPoint veryTip( origin ); veryTip.SetZ( (origin.Z() - length) ); spiral.push_back(veryTip); spiral.push_back(topEdge); } // End while std::copy( top.begin(), top.end(), std::inserter( result, result.begin() ) ); std::copy( spiral.begin(), spiral.end(), std::inserter( result, result.end() ) ); std::copy( countersink.begin(), countersink.end(), std::inserter( result, result.end() ) ); return(result); } // End DrillBitVertices() routine