⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs_text.cpp

📁 qcad2.05可用于windows和linux的源码
💻 CPP
字号:
/****************************************************************************** $Id: rs_text.cpp 1952 2005-01-07 15:21:19Z andrew $**** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.**** This file is part of the qcadlib Library project.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid qcadlib Professional Edition licenses may use ** this file in accordance with the qcadlib Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.ribbonsoft.com for further details.**** Contact info@ribbonsoft.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "rs_text.h"#include "rs_fontlist.h"#include "rs_insert.h"/** * Constructor. */RS_Text::RS_Text(RS_EntityContainer* parent,                 const RS_TextData& d)        : RS_EntityContainer(parent), data(d) {    usedTextHeight = 0.0;    usedTextWidth = 0.0;    setText(data.text);}/** * Sets a new text. The entities representing the  * text are updated. */void RS_Text::setText(const RS_String& t) {    data.text = t;    // handle some special flags embedded in the text:    if (data.text.left(4)=="\\A0;") {        data.text = data.text.mid(4);        data.valign = RS2::VAlignBottom;    } else if (data.text.left(4)=="\\A1;") {        data.text = data.text.mid(4);        data.valign = RS2::VAlignMiddle;    } else if (data.text.left(4)=="\\A2;") {        data.text = data.text.mid(4);        data.valign = RS2::VAlignTop;    }    if (data.updateMode==RS2::Update) {        update();        //calculateBorders();    }}/** * Gets the alignment as an int. * * @return  1: top left ... 9: bottom right */int RS_Text::getAlignment() {    if (data.valign==RS2::VAlignTop) {        if (data.halign==RS2::HAlignLeft) {            return 1;        } else if (data.halign==RS2::HAlignCenter) {            return 2;        } else if (data.halign==RS2::HAlignRight) {            return 3;        }    } else if (data.valign==RS2::VAlignMiddle) {        if (data.halign==RS2::HAlignLeft) {            return 4;        } else if (data.halign==RS2::HAlignCenter) {            return 5;        } else if (data.halign==RS2::HAlignRight) {            return 6;        }    } else if (data.valign==RS2::VAlignBottom) {        if (data.halign==RS2::HAlignLeft) {            return 7;        } else if (data.halign==RS2::HAlignCenter) {            return 8;        } else if (data.halign==RS2::HAlignRight) {            return 9;        }    }    return 1;}/** * Sets the alignment from an int. * * @param a 1: top left ... 9: bottom right */void RS_Text::setAlignment(int a) {    switch (a%3) {    default:    case 1:        data.halign = RS2::HAlignLeft;        break;    case 2:        data.halign = RS2::HAlignCenter;        break;    case 0:        data.halign = RS2::HAlignRight;        break;    }    switch ((int)ceil(a/3.0)) {    default:    case 1:        data.valign = RS2::VAlignTop;        break;    case 2:        data.valign = RS2::VAlignMiddle;        break;    case 3:        data.valign = RS2::VAlignBottom;        break;    }}/** * @return Number of lines in this text entity.  */int RS_Text::getNumberOfLines() {    int c=1;    for (int i=0; i<(int)data.text.length(); ++i) {        if (data.text.at(i).unicode()==0x0A) {            c++;        }    }    return c;}/** * Updates the Inserts (letters) of this text. Called when the  * text or it's data, position, alignment, .. changes. * This method also updates the usedTextWidth / usedTextHeight property. */void RS_Text::update() {    RS_DEBUG->print("RS_Text::update");    clear();    if (isUndone()) {        return;    }    usedTextWidth = 0.0;    usedTextHeight = 0.0;    RS_Font* font = RS_FONTLIST->requestFont(data.style);    if (font==NULL) {        return;    }    RS_Vector letterPos = RS_Vector(0.0, -9.0);    RS_Vector letterSpace = RS_Vector(font->getLetterSpacing(), 0.0);    RS_Vector space = RS_Vector(font->getWordSpacing(), 0.0);    int lineCounter = 0;    // Every single text line gets stored in this entity container    //  so we can move the whole line around easely:    RS_EntityContainer* oneLine = new RS_EntityContainer(this);    // First every text line is created with    //   alignement: top left    //   angle: 0    //   height: 9.0    // Rotation, scaling and centering is done later    // For every letter:    for (int i=0; i<(int)data.text.length(); ++i) {        switch (data.text.at(i).unicode()) {        case 0x0A:            // line feed:            updateAddLine(oneLine, lineCounter++);            oneLine = new RS_EntityContainer(this);            letterPos = RS_Vector(0.0, -9.0);            break;        case 0x20:            // Space:            letterPos+=space;            break;        case 0x5C: {                // code (e.g. \S, \P, ..)                i++;                int ch = data.text.at(i).unicode();                switch (ch) {                case 'P':                    updateAddLine(oneLine, lineCounter++);                    oneLine = new RS_EntityContainer(this);                    letterPos = RS_Vector(0.0, -9.0);                    break;                case 'S': {                        RS_String up;                        RS_String dw;                        //letterPos += letterSpace;                        // get upper string:                        i++;                        while (data.text.at(i).unicode()!='^' &&						       //data.text.at(i).unicode()!='/' &&						       data.text.at(i).unicode()!='\\' &&						       //data.text.at(i).unicode()!='#' &&                                i<(int)data.text.length()) {                            up += data.text.at(i);                            i++;                        }						                        i++;												if (data.text.at(i-1).unicode()=='^' &&						     data.text.at(i).unicode()==' ') {							i++;						}						                        // get lower string:                        while (data.text.at(i).unicode()!=';' &&                                i<(int)data.text.length()) {                            dw += data.text.at(i);                            i++;                        }                        // add texts:                        RS_Text* upper =                            new RS_Text(                                oneLine,                                RS_TextData(letterPos + RS_Vector(0.0,9.0),                                            4.0, 100.0, RS2::VAlignTop, 											RS2::HAlignLeft,                                            RS2::LeftToRight, RS2::Exact,                                            1.0, up, data.style,                                            0.0, RS2::Update));						upper->setLayer(NULL);                    	upper->setPen(RS_Pen(RS2::FlagInvalid));						oneLine->addEntity(upper);                        RS_Text* lower =                            new RS_Text(                                oneLine,                                RS_TextData(letterPos+RS_Vector(0.0,4.0),                                            4.0, 100.0, RS2::VAlignTop, 											RS2::HAlignLeft,                                            RS2::LeftToRight, RS2::Exact,                                            1.0, dw, data.style,                                            0.0, RS2::Update));						lower->setLayer(NULL);                    	lower->setPen(RS_Pen(RS2::FlagInvalid));                        oneLine->addEntity(lower);                        // move cursor:                        upper->calculateBorders();                        lower->calculateBorders();                        double w1 = upper->getSize().x;                        double w2 = lower->getSize().x;                        if (w1>w2) {                            letterPos += RS_Vector(w1, 0.0);                        } else {                            letterPos += RS_Vector(w2, 0.0);                        }                        letterPos += letterSpace;                    }                    break;                default:                    break;                }            }            break;        default: {                // One Letter:                if (font->findLetter(QString(data.text.at(i))) != NULL) {									RS_DEBUG->print("RS_Text::update: insert a "					  "letter at pos: %f/%f", letterPos.x, letterPos.y);                    RS_InsertData d(RS_String(data.text.at(i)),                                    letterPos,                                    RS_Vector(1.0, 1.0),                                    0.0,                                    1,1, RS_Vector(0.0,0.0),                                    font->getLetterList(), RS2::NoUpdate);					                    RS_Insert* letter = new RS_Insert(this, d);                    RS_Vector letterWidth;                    letter->setPen(RS_Pen(RS2::FlagInvalid));                    letter->setLayer(NULL);                    letter->update();                    letter->forcedCalculateBorders();										// until 2.0.4.5:                    //letterWidth = RS_Vector(letter->getSize().x, 0.0);					// from 2.0.4.6:                    letterWidth = RS_Vector(letter->getMax().x-letterPos.x, 0.0);					                    oneLine->addEntity(letter);                    // next letter position:                    letterPos += letterWidth;                    letterPos += letterSpace;                }            }            break;        }    }    updateAddLine(oneLine, lineCounter);    usedTextHeight -= data.height*data.lineSpacingFactor*1.6                      - data.height;    forcedCalculateBorders();	    RS_DEBUG->print("RS_Text::update: OK");}/** * Used internally by update() to add a text line created with  * default values and alignment to this text container. * * @param textLine The text line. * @param lineCounter Line number. */void RS_Text::updateAddLine(RS_EntityContainer* textLine, int lineCounter) {    RS_DEBUG->print("RS_Text::updateAddLine: width: %f", textLine->getSize().x);	//textLine->forcedCalculateBorders();    //RS_DEBUG->print("RS_Text::updateAddLine: width 2: %f", textLine->getSize().x);    // Move to correct line position:    textLine->move(RS_Vector(0.0, -9.0 * lineCounter                             * data.lineSpacingFactor * 1.6));	textLine->forcedCalculateBorders();	RS_Vector textSize = textLine->getSize();    	RS_DEBUG->print("RS_Text::updateAddLine: width 2: %f", textSize.x);    // Horizontal Align:    switch (data.halign) {    case RS2::HAlignCenter:		RS_DEBUG->print("RS_Text::updateAddLine: move by: %f", -textSize.x/2.0);        textLine->move(RS_Vector(-textSize.x/2.0, 0.0));        break;    case RS2::HAlignRight:        textLine->move(RS_Vector(-textSize.x, 0.0));        break;    default:        break;    }    // Vertical Align:    double vSize = getNumberOfLines()*9.0*data.lineSpacingFactor*1.6                   - (9.0*data.lineSpacingFactor*1.6 - 9.0);    switch (data.valign) {    case RS2::VAlignMiddle:        textLine->move(RS_Vector(0.0, vSize/2.0));        break;    case RS2::VAlignBottom:        textLine->move(RS_Vector(0.0, vSize));        break;    default:        break;    }    // Scale:    textLine->scale(RS_Vector(0.0,0.0),                    RS_Vector(data.height/9.0, data.height/9.0));    textLine->forcedCalculateBorders();    // Update actual text size (before rotating, after scaling!):    if (textLine->getSize().x>usedTextWidth) {        usedTextWidth = textLine->getSize().x;    }    usedTextHeight += data.height*data.lineSpacingFactor*1.6;    // Rotate:    textLine->rotate(RS_Vector(0.0,0.0), data.angle);    // Move:    textLine->move(data.insertionPoint);    textLine->setPen(RS_Pen(RS2::FlagInvalid));    textLine->setLayer(NULL);    textLine->forcedCalculateBorders();    addEntity(textLine);}RS_VectorSolutions RS_Text::getRefPoints() {	RS_VectorSolutions ret(data.insertionPoint);	return ret;}    	RS_Vector RS_Text::getNearestRef(const RS_Vector& coord,                                     double* dist) {	//return getRefPoints().getClosest(coord, dist);	return RS_Entity::getNearestRef(coord, dist);}void RS_Text::move(RS_Vector offset) {    data.insertionPoint.move(offset);    update();}void RS_Text::rotate(RS_Vector center, double angle) {    data.insertionPoint.rotate(center, angle);    data.angle = RS_Math::correctAngle(data.angle+angle);    update();}void RS_Text::scale(RS_Vector center, RS_Vector factor) {    data.insertionPoint.scale(center, factor);    data.width*=factor.x;    data.height*=factor.x;    update();}void RS_Text::mirror(RS_Vector axisPoint1, RS_Vector axisPoint2) {    data.insertionPoint.mirror(axisPoint1, axisPoint2);    //double ang = axisPoint1.angleTo(axisPoint2);    bool readable = RS_Math::isAngleReadable(data.angle);    RS_Vector vec;    vec.setPolar(1.0, data.angle);    vec.mirror(RS_Vector(0.0,0.0), axisPoint2-axisPoint1);    data.angle = vec.angle();    bool corr;    data.angle = RS_Math::makeAngleReadable(data.angle, readable, &corr);    if (corr) {        if (data.halign==RS2::HAlignLeft) {            data.halign=RS2::HAlignRight;        } else if (data.halign==RS2::HAlignRight) {            data.halign=RS2::HAlignLeft;        }    } else {        if (data.valign==RS2::VAlignTop) {            data.valign=RS2::VAlignBottom;        } else if (data.valign==RS2::VAlignBottom) {            data.valign=RS2::VAlignTop;        }    }    update();}bool RS_Text::hasEndpointsWithinWindow(RS_Vector /*v1*/, RS_Vector /*v2*/) {    return false;}/** * Implementations must stretch the given range of the entity  * by the given offset. */void RS_Text::stretch(RS_Vector firstCorner,                      RS_Vector secondCorner,                      RS_Vector offset) {    if (getMin().isInWindow(firstCorner, secondCorner) &&            getMax().isInWindow(firstCorner, secondCorner)) {        move(offset);    }}/** * Dumps the point's data to stdout. */std::ostream& operator << (std::ostream& os, const RS_Text& p) {    os << " Text: " << p.getData() << "\n";    return os;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -