void PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) { SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); // FIXME: this snapping should be done together with knowing whether control was pressed. If GDK_CONTROL_MASK, then constrained snapping should be used. Geom::Point p_snapped = snap_knot_position(p, state); // get angle from current transform gdouble theta = sp_pattern_extract_theta(pat); // Get the new scale from the position of the knotholder Geom::Point d = p_snapped - sp_pattern_extract_trans(pat); gdouble pat_x = pattern_width(pat); gdouble pat_y = pattern_height(pat); Geom::Scale scl(1); if ( state & GDK_CONTROL_MASK ) { // if ctrl is pressed: use 1:1 scaling gdouble pat_h = hypot(pat_x, pat_y); scl = Geom::Scale(d.length() / pat_h); } else { d *= Geom::Rotate(-theta); scl = Geom::Scale(d[Geom::X] / pat_x, d[Geom::Y] / pat_y); } Geom::Affine rot = (Geom::Affine)scl * Geom::Rotate(theta); Geom::Point const t = sp_pattern_extract_trans(pat); rot[4] = t[Geom::X]; rot[5] = t[Geom::Y]; item->adjust_pattern(rot, true); item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); }
void KnotPropertiesDialog::_setKnotPoint(Geom::Point knotpoint, Glib::ustring const unit_name) { _unit_name = unit_name; _knot_x_entry.set_value( Inkscape::Util::Quantity::convert(knotpoint.x(), "px", _unit_name)); _knot_y_entry.set_value( Inkscape::Util::Quantity::convert(knotpoint.y(), "px", _unit_name)); _knot_x_label.set_label(g_strdup_printf(_("Position X (%s):"), _unit_name.c_str())); _knot_y_label.set_label(g_strdup_printf(_("Position Y (%s):"), _unit_name.c_str())); }
void Canvas::translate(geom::Point const& pt) { glTranslatef(pt.x(),pt.y(),0.0f); #ifdef DEBUG const GLenum err = glGetError(); if(err != GL_NO_ERROR){ CINAMO_EXCEPTION(Exception, "[BUG] Failed to exec glTranslatef: 0x%08x", err); } #endif }
void Canvas::drawLine(const float width, Color const& color, geom::Point const& start, geom::Point const& end, const float depth) { if(color.isInvalid() || !(width > 0)){ return; } this->setLineWidth(width); this->setColor(color); this->setOperation(Lines); pushVertex(start.x(), start.y(), depth); pushVertex(end.x() , end.y(), depth); }
geom::Area PredefinedSymRenderer::renderSyms( Canvas& cv, geom::Point const& point, SymList const& str, float depth) { float x=0.0f; for(unsigned int symbol : str){ auto it = this->entryTable_.find(symbol); if(it == this->entryTable_.end()){ this->log().w(TAG, "Unknown symbol: %d", symbol); continue; } Entry const& ent( it->second ); Image& img = renderBuffer_[ent.spriteNo]; geom::Point rendered( point.x()+x, point.y() ); img.add(rendered, ent.areaInSprite); x += ent.areaInSprite.width(); } return geom::Area(point, geom::Box(x,this->height_)); }
void RegisteredVector::setValue(Geom::Point const & p) { if (!_polar_coords) { Point::setValue(p); } else { Geom::Point polar; polar[Geom::X] = atan2(p) *180/M_PI; polar[Geom::Y] = p.length(); Point::setValue(polar); } }
void Path::DoButt(Shape *dest, double width, ButtType butt, Geom::Point pos, Geom::Point dir, int &leftNo, int &rightNo) { Geom::Point nor; nor = dir.ccw(); if (butt == butt_square) { Geom::Point x; x = pos + width * dir + width * nor; int bleftNo = dest->AddPoint (x); x = pos + width * dir - width * nor; int brightNo = dest->AddPoint (x); x = pos + width * nor; leftNo = dest->AddPoint (x); x = pos - width * nor; rightNo = dest->AddPoint (x); dest->AddEdge (rightNo, brightNo); dest->AddEdge (brightNo, bleftNo); dest->AddEdge (bleftNo, leftNo); } else if (butt == butt_pointy) { leftNo = dest->AddPoint (pos + width * nor); rightNo = dest->AddPoint (pos - width * nor); int mid = dest->AddPoint (pos + width * dir); dest->AddEdge (rightNo, mid); dest->AddEdge (mid, leftNo); } else if (butt == butt_round) { const Geom::Point sx = pos + width * nor; const Geom::Point ex = pos - width * nor; leftNo = dest->AddPoint (sx); rightNo = dest->AddPoint (ex); RecRound (dest, rightNo, leftNo, ex, sx, -nor, nor, pos, width); } else { leftNo = dest->AddPoint (pos + width * nor); rightNo = dest->AddPoint (pos - width * nor); dest->AddEdge (rightNo, leftNo); } }
// find the position at which node "newOne" should be inserted in the subtree rooted here // we want to order with respect to the order of intersections with the sweepline, currently // lying at y=px[1]. // px is the upper endpoint of newOne int SweepTree::Find(Geom::Point const &px, SweepTree *newOne, SweepTree *&insertL, SweepTree *&insertR, bool sweepSens) { // get the edge associated with this node: one point+one direction // since we're dealing with line, the direction (bNorm) is taken downwards Geom::Point bOrig, bNorm; bOrig = src->pData[src->getEdge(bord).st].rx; bNorm = src->eData[bord].rdx; if (src->getEdge(bord).st > src->getEdge(bord).en) { bNorm = -bNorm; } // rotate to get the normal to the edge bNorm=bNorm.ccw(); Geom::Point diff; diff = px - bOrig; // compute (px-orig)^dir to know on which side of this edge the point px lies double y = 0; //if ( startPoint == newOne->startPoint ) { // y=0; //} else { y = dot(bNorm, diff); //} //y*=invDirLength; if (fabs(y) < 0.000001) { // that damn point px lies on me, so i need to consider to direction of the edge in // newOne to know if it goes toward my left side or my right side // sweepSens is needed (actually only used by the Scan() functions) because if the sweepline goes upward, // signs change // prendre en compte les directions Geom::Point nNorm; nNorm = newOne->src->eData[newOne->bord].rdx; if (newOne->src->getEdge(newOne->bord).st > newOne->src->getEdge(newOne->bord).en) { nNorm = -nNorm; } nNorm=nNorm.ccw(); if (sweepSens) { y = cross(nNorm, bNorm); } else { y = cross(bNorm, nNorm); } if (y == 0) { y = dot(bNorm, nNorm); if (y == 0) { insertL = this; insertR = static_cast<SweepTree *>(elem[RIGHT]); return found_exact; } } } if (y < 0) { if (son[LEFT]) { return (static_cast<SweepTree *>(son[LEFT]))->Find(px, newOne, insertL, insertR, sweepSens); } else { insertR = this; insertL = static_cast<SweepTree *>(elem[LEFT]); if (insertL) { return found_between; } else { return found_on_left; } } } else { if (son[RIGHT]) { return (static_cast<SweepTree *>(son[RIGHT]))->Find(px, newOne, insertL, insertR, sweepSens); } else { insertL = this; insertR = static_cast<SweepTree *>(elem[RIGHT]); if (insertR) { return found_between; } else { return found_on_right; } } } return not_found; }
Geom::Rect Layout::characterBoundingBox(iterator const &it, double *rotation) const { Geom::Point top_left, bottom_right; unsigned char_index = it._char_index; if (_path_fitted) { double cluster_half_width = 0.0; for (int glyph_index = _characters[char_index].in_glyph ; _glyphs[glyph_index].in_character == char_index ; glyph_index++) cluster_half_width += _glyphs[glyph_index].width; cluster_half_width *= 0.5; double midpoint_offset = _characters[char_index].span(this).x_start + _characters[char_index].x + cluster_half_width; int unused = 0; Path::cut_position *midpoint_otp = const_cast<Path*>(_path_fitted)->CurvilignToPosition(1, &midpoint_offset, unused); if (midpoint_offset >= 0.0 && midpoint_otp != NULL && midpoint_otp[0].piece >= 0) { Geom::Point midpoint; Geom::Point tangent; Span const &span = _characters[char_index].span(this); const_cast<Path*>(_path_fitted)->PointAndTangentAt(midpoint_otp[0].piece, midpoint_otp[0].t, midpoint, tangent); top_left[Geom::X] = midpoint[Geom::X] - cluster_half_width; top_left[Geom::Y] = midpoint[Geom::Y] - span.line_height.ascent; bottom_right[Geom::X] = midpoint[Geom::X] + cluster_half_width; bottom_right[Geom::Y] = midpoint[Geom::Y] + span.line_height.descent; Geom::Point normal = tangent.cw(); top_left += span.baseline_shift * normal; bottom_right += span.baseline_shift * normal; if (rotation) *rotation = atan2(tangent[1], tangent[0]); } g_free(midpoint_otp); } else { if (it._char_index == _characters.size()) { top_left[Geom::X] = bottom_right[Geom::X] = _chunks.back().left_x + _spans.back().x_end; char_index--; } else { double span_x = _spans[_characters[it._char_index].in_span].x_start + _characters[it._char_index].chunk(this).left_x; top_left[Geom::X] = span_x + _characters[it._char_index].x; if (it._char_index + 1 == _characters.size() || _characters[it._char_index + 1].in_span != _characters[it._char_index].in_span) bottom_right[Geom::X] = _spans[_characters[it._char_index].in_span].x_end + _characters[it._char_index].chunk(this).left_x; else bottom_right[Geom::X] = span_x + _characters[it._char_index + 1].x; } double baseline_y = _characters[char_index].line(this).baseline_y + _characters[char_index].span(this).baseline_shift; if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { double span_height = _spans[_characters[char_index].in_span].line_height.ascent + _spans[_characters[char_index].in_span].line_height.descent; top_left[Geom::Y] = top_left[Geom::X]; top_left[Geom::X] = baseline_y - span_height * 0.5; bottom_right[Geom::Y] = bottom_right[Geom::X]; bottom_right[Geom::X] = baseline_y + span_height * 0.5; } else { top_left[Geom::Y] = baseline_y - _spans[_characters[char_index].in_span].line_height.ascent; bottom_right[Geom::Y] = baseline_y + _spans[_characters[char_index].in_span].line_height.descent; } if (rotation) { if (it._glyph_index == -1) *rotation = 0.0; else if (it._glyph_index == (int)_glyphs.size()) *rotation = _glyphs.back().rotation; else *rotation = _glyphs[it._glyph_index].rotation; } } return Geom::Rect(top_left, bottom_right); }
void Path::DoRightJoin (Shape * dest, double width, JoinType join, Geom::Point pos, Geom::Point prev, Geom::Point next, double miter, double /*prevL*/, double /*nextL*/, int &rightStNo, int &rightEnNo,int pathID,int pieceID,double tID) { const Geom::Point pnor=prev.ccw(); const Geom::Point nnor=next.ccw(); double angSi = cross (next,prev); if (angSi > -0.0001 && angSi < 0.0001) { double angCo = dot (prev, next); if (angCo > 0.9999) { // tout droit rightEnNo = rightStNo = dest->AddPoint (pos - width*pnor); } else { // demi-tour rightEnNo = dest->AddPoint (pos + width*pnor); rightStNo = dest->AddPoint (pos - width*pnor); int nEdge=dest->AddEdge (rightStNo, rightEnNo); if ( dest->hasBackData() ) { dest->ebData[nEdge].pathID=pathID; dest->ebData[nEdge].pieceID=pieceID; dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; } } return; } if (angSi < 0) { if (join == join_pointy) { rightStNo = dest->AddPoint (pos - width*pnor); rightEnNo = dest->AddPoint (pos - width*nnor); const Geom::Point biss = StrokeNormalize (pnor + nnor); double c2 = dot (biss, nnor); double l = width / c2; double emiter = width * c2; if (emiter < miter) emiter = miter; if (l <= emiter) { int nrightStNo = dest->AddPoint (pos - l * biss); int nEdge=dest->AddEdge (rightStNo, nrightStNo); if ( dest->hasBackData() ) { dest->ebData[nEdge].pathID=pathID; dest->ebData[nEdge].pieceID=pieceID; dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; } nEdge=dest->AddEdge (nrightStNo, rightEnNo); if ( dest->hasBackData() ) { dest->ebData[nEdge].pathID=pathID; dest->ebData[nEdge].pieceID=pieceID; dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; } } else { double s2 = cross (biss, nnor); double dec = (l - emiter) * c2 / s2; const Geom::Point tbiss=biss.ccw(); int nrightStNo = dest->AddPoint (pos - emiter*biss - dec*tbiss); int nrightEnNo = dest->AddPoint (pos - emiter*biss + dec*tbiss); int nEdge=dest->AddEdge (rightStNo, nrightStNo); if ( dest->hasBackData() ) { dest->ebData[nEdge].pathID=pathID; dest->ebData[nEdge].pieceID=pieceID; dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; } nEdge=dest->AddEdge (nrightStNo, nrightEnNo); if ( dest->hasBackData() ) { dest->ebData[nEdge].pathID=pathID; dest->ebData[nEdge].pieceID=pieceID; dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; } nEdge=dest->AddEdge (nrightEnNo, rightEnNo); if ( dest->hasBackData() ) { dest->ebData[nEdge].pathID=pathID; dest->ebData[nEdge].pieceID=pieceID; dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; } } } else if (join == join_round) { const Geom::Point sx = pos - width * pnor; rightStNo = dest->AddPoint (sx); const Geom::Point ex = pos - width * nnor; rightEnNo = dest->AddPoint (ex); RecRound(dest, rightStNo, rightEnNo, sx, ex, -pnor, -nnor ,pos, width); } else { rightStNo = dest->AddPoint (pos - width * pnor); rightEnNo = dest->AddPoint (pos - width * nnor); int nEdge=dest->AddEdge (rightStNo, rightEnNo); if ( dest->hasBackData() ) { dest->ebData[nEdge].pathID=pathID; dest->ebData[nEdge].pieceID=pieceID; dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; } } } else { /* Geom::Point biss; biss=next.x-prev.x; biss.y=next.y-prev.y; double c2=cross(next,biss); double l=width/c2; double projn=l*(dot(biss,next)); double projp=-l*(dot(biss,prev)); if ( projp <= 0.5*prevL && projn <= 0.5*nextL ) { double x,y; x=pos.x+l*biss.x; y=pos.y+l*biss.y; rightEnNo=rightStNo=dest->AddPoint(x,y); } else {*/ rightStNo = dest->AddPoint (pos - width*pnor); rightEnNo = dest->AddPoint (pos - width*nnor); int midNo = dest->AddPoint (pos); int nEdge=dest->AddEdge (rightStNo, midNo); if ( dest->hasBackData() ) { dest->ebData[nEdge].pathID=pathID; dest->ebData[nEdge].pieceID=pieceID; dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; } nEdge=dest->AddEdge (midNo, rightEnNo); if ( dest->hasBackData() ) { dest->ebData[nEdge].pathID=pathID; dest->ebData[nEdge].pieceID=pieceID; dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; } // } } }
void Path::DoJoin (Shape *dest, double width, JoinType join, Geom::Point pos, Geom::Point prev, Geom::Point next, double miter, double /*prevL*/, double /*nextL*/, int *stNo, int *enNo) { Geom::Point pnor = prev.ccw(); Geom::Point nnor = next.ccw(); double angSi = cross(next, prev); /* FIXED: this special case caused bug 1028953 */ if (angSi > -0.0001 && angSi < 0.0001) { double angCo = dot (prev, next); if (angCo > 0.9999) { // tout droit stNo[LEFT] = enNo[LEFT] = dest->AddPoint(pos + width * pnor); stNo[RIGHT] = enNo[RIGHT] = dest->AddPoint(pos - width * pnor); } else { // demi-tour const Geom::Point sx = pos + width * pnor; const Geom::Point ex = pos - width * pnor; stNo[LEFT] = enNo[RIGHT] = dest->AddPoint (sx); stNo[RIGHT] = enNo[LEFT] = dest->AddPoint (ex); if (join == join_round) { RecRound (dest, enNo[LEFT], stNo[LEFT], ex, sx, -pnor, pnor, pos, width); dest->AddEdge(stNo[RIGHT], enNo[RIGHT]); } else { dest->AddEdge(enNo[LEFT], stNo[LEFT]); dest->AddEdge(stNo[RIGHT], enNo[RIGHT]); // two times because both are crossing each other } } return; } if (angSi < 0) { int midNo = dest->AddPoint(pos); stNo[LEFT] = dest->AddPoint(pos + width * pnor); enNo[LEFT] = dest->AddPoint(pos + width * nnor); dest->AddEdge(enNo[LEFT], midNo); dest->AddEdge(midNo, stNo[LEFT]); if (join == join_pointy) { stNo[RIGHT] = dest->AddPoint(pos - width * pnor); enNo[RIGHT] = dest->AddPoint(pos - width * nnor); const Geom::Point biss = StrokeNormalize(prev - next); double c2 = dot(biss, nnor); double l = width / c2; double emiter = width * c2; if (emiter < miter) { emiter = miter; } if (fabs(l) < miter) { int const n = dest->AddPoint(pos - l * biss); dest->AddEdge(stNo[RIGHT], n); dest->AddEdge(n, enNo[RIGHT]); } else { dest->AddEdge(stNo[RIGHT], enNo[RIGHT]); } } else if (join == join_round) { Geom::Point sx = pos - width * pnor; stNo[RIGHT] = dest->AddPoint(sx); Geom::Point ex = pos - width * nnor; enNo[RIGHT] = dest->AddPoint(ex); RecRound(dest, stNo[RIGHT], enNo[RIGHT], sx, ex, -pnor, -nnor, pos, width); } else { stNo[RIGHT] = dest->AddPoint(pos - width * pnor); enNo[RIGHT] = dest->AddPoint(pos - width * nnor); dest->AddEdge(stNo[RIGHT], enNo[RIGHT]); } } else { int midNo = dest->AddPoint(pos); stNo[RIGHT] = dest->AddPoint(pos - width * pnor); enNo[RIGHT] = dest->AddPoint(pos - width * nnor); dest->AddEdge(stNo[RIGHT], midNo); dest->AddEdge(midNo, enNo[RIGHT]); if (join == join_pointy) { stNo[LEFT] = dest->AddPoint(pos + width * pnor); enNo[LEFT] = dest->AddPoint(pos + width * nnor); const Geom::Point biss = StrokeNormalize(next - prev); double c2 = dot(biss, nnor); double l = width / c2; double emiter = width * c2; if (emiter < miter) { emiter = miter; } if ( fabs(l) < miter) { int const n = dest->AddPoint (pos + l * biss); dest->AddEdge (enNo[LEFT], n); dest->AddEdge (n, stNo[LEFT]); } else { dest->AddEdge (enNo[LEFT], stNo[LEFT]); } } else if (join == join_round) { Geom::Point sx = pos + width * pnor; stNo[LEFT] = dest->AddPoint(sx); Geom::Point ex = pos + width * nnor; enNo[LEFT] = dest->AddPoint(ex); RecRound(dest, enNo[LEFT], stNo[LEFT], ex, sx, nnor, pnor, pos, width); } else { stNo[LEFT] = dest->AddPoint(pos + width * pnor); enNo[LEFT] = dest->AddPoint(pos + width * nnor); dest->AddEdge(enNo[LEFT], stNo[LEFT]); } } }