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()));
}
Beispiel #3
0
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
}
Beispiel #4
0
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_));
}
Beispiel #6
0
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);
    }
}
Beispiel #8
0
// 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;
}
Beispiel #9
0
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]);
        }
    }
}