Exemple #1
0
// ****************************************************************************
//
//  Function Name:	RWindowView::RWindowView( )
//
//  Description:		Render this views background
//
//  Returns:			Nothing
//
//  Exceptions:		None
//
// ****************************************************************************
//
void RWindowView::RenderBackground( RDrawingSurface& drawingSurface, const R2dTransform&, const RIntRect& rcRender ) const
	{
	// Fill in the background
	if( !drawingSurface.IsPrinting( ) )
		{
		RColor	backgroundColor	= GetBackgroundColor( );
		if ( backgroundColor.GetFillMethod() == RColor::kSolid )
			{
			RSolidColor	solid	= backgroundColor.GetSolidColor( );
			//	Check for something close to TRUE GRAY and alter it slightly
#ifdef _WINDOWS
			const YColorComponent	kHitBits			= 0xC0;
			const YColorComponent	kNewColor		= 0x77;
			const YColorComponent	kGrayColor		= 0x80;
#elif	defined( MAC )
			const YColorComponent	kHitBits			= 0xF000;
			const YColorComponent	kNewColor		= 0x7777;
			const YColorComponent	kGrayColor		= 0x8000;
#endif	//	_WINDOWS or MAC
			YColorComponent	redColor		= (solid.GetRed( ) & kHitBits);
			YColorComponent	greenColor	= (solid.GetGreen( ) & kHitBits);
			YColorComponent	blueColor	= (solid.GetBlue( ) & kHitBits);
			if ( (kGrayColor == redColor) && (redColor == greenColor) && (greenColor == blueColor) )
				{
				backgroundColor = RSolidColor( kNewColor, kNewColor, kNewColor );
				}
			}
		drawingSurface.SetForegroundMode( kNormal );
		drawingSurface.SetFillColor( backgroundColor );
		drawingSurface.FillRectangle( rcRender );
		}
	}
Exemple #2
0
HRESULT RPathOutlineAttribImp::SetColor( const RColor& crColor )
{
	if (RColor::kSolid != crColor.GetFillMethod())
		return E_INVALIDARG;

	m_sOutlineFormat.m_yPenColor = crColor.GetSolidColor();
	m_pPathDocument->InvalidateAllViews();

	return S_OK;
}
Exemple #3
0
/**
 * Creates a color from the given CAD code (index 0...256).
 */
RColor RColor::createFromCadIndex(int code) {
    // special colors:
    if (code==0) {
        return RColor(RColor::ByBlock);
    }
    if (code==256) {
        return RColor(RColor::ByLayer);
    }

    // normal indexed colors:
    if (code>0 && code<256) {
        RColor c;
        c.setRgbF(cadColors[code][0], cadColors[code][1], cadColors[code][2]);
        return c;
    }

    return RColor();
}
Exemple #4
0
QIcon RColor::getIcon(const RColor& color, const QSize& size) {
    init();

    if (iconMap.contains(QPair<RColor, QPair<int, int> >(color, QPair<int, int>(size.width(), size.height())))) {
        return iconMap[QPair<RColor, QPair<int, int> >(color, QPair<int, int>(size.width(), size.height()))];
    }

    RColor col = color;
    if (color.isByLayer() || color.isByBlock() || /*color == RColor(Qt::black,
            RColor::BlackWhite) ||*/ !color.isValid()) {
        col = Qt::white;
    }
    QImage img(size, QImage::Format_ARGB32_Premultiplied);
    img.fill(0);
    QPainter painter(&img);
    int w = img.width();
    int h = img.height();
    //    painter.setCompositionMode(QPainter::CompositionMode_Source);
    painter.fillRect(0, 0, w, h, col);
    if (!color.isValid()) {
        // icon for "Other colors..."
        QLinearGradient grad(0, 0, w, 0);
        grad.setColorAt(0, Qt::red);
        grad.setColorAt(0.33, Qt::yellow);
        grad.setColorAt(0.66, Qt::blue);
        grad.setColorAt(1, Qt::green);
        painter.fillRect(QRect(0, 0, w, h), grad);
    } /*else if (color == RColor(Qt::black, RColor::BlackWhite) || color
            == RColor(Qt::white, RColor::BlackWhite)) {
        // icon for black / white
        painter.setRenderHint(QPainter::Antialiasing);
        QPainterPath path;
        path.moveTo(0, 0);
        path.lineTo(w, 0);
        path.lineTo(w, h);
        painter.fillPath(path, Qt::black);
        painter.setRenderHint(QPainter::Antialiasing, false);
    }*/ else if (col.alpha() != 255) {
        // indicate alpha by an inset
        QBrush opaqueBrush = col;
        col.setAlpha(255);
        opaqueBrush.setColor(col);
        painter.fillRect(w / 4, h / 4, w / 2, h / 2, opaqueBrush);
    }
    painter.setPen(Qt::black);
    painter.drawRect(0, 0, w - 1, h - 1);
    painter.end();
    QIcon ret(QPixmap::fromImage(img));
    iconMap.insert(QPair<RColor, QPair<int, int> >(color, QPair<int, int>(size.width(), size.height())), ret);
    return ret;
}
Exemple #5
0
/**
 * Stream operator for QDebug
 */
QDebug operator<<(QDebug dbg, const RColor& c) {
    if (c.isValid()) {
        if (c.isByLayer()) {
            dbg.nospace() << "RColor(ByLayer)";
        } else if (c.isByBlock()) {
            dbg.nospace() << "RColor(ByBlock)";
        } else {
            dbg.nospace() << "RColor(RGBA: " << c.red() << ", " << c.green() << ", "
                    << c.blue() << ", " << c.alpha() << ")";
        }
    } else {
        dbg.nospace() << "RColor(invalid)";
    }
    return dbg.space();
}
//****************************************************************************
//
// Function Name: SetColor
//
// Description:   Stores the current color for use in gradient option 
//						determination, and then updates the gradient selections.
//
// Returns:       None
//
// Exceptions:	   None
//
//****************************************************************************
void RColorDialog::SetColor( const RColor& crColor )
{
	if (RColor::kBitmap == crColor.GetFillMethod())
	{
		if (m_dlgColorPhoto.IsColorPhoto( crColor ))
		{
			m_dlgColorPhoto.SetColor( crColor );
			m_nStartPage = 2;
		}
		else
		{
			m_dlgColorTexture.SetColor( crColor );
			m_nStartPage = 1;
		}
	}
	else
	{
		m_dlgColorPalette.SetColor( crColor );
		m_nStartPage = 0;
	}
}
Exemple #7
0
void DisplayList::UpdateRect(SRECT* clip)
{
	if ( bits->LockBits() ) {
		raster.Attach(bits, clip, antialias);
		raster.BeginPaint();

		// Add the background edges
		REdge bkEdges[2];
		RColor bkColor;
		if ( backgroundColor.all != 0 ) {
			// Set up the color
			bkColor.SetUp(&raster);
			bkColor.order = 0;
			bkColor.rgb.alpha = 255;
			bkColor.rgb.red   = backgroundColor.rgb.red;
			bkColor.rgb.green = backgroundColor.rgb.green;
			bkColor.rgb.blue  = backgroundColor.rgb.blue;
			bkColor.BuildCache();

			// Set up the edges
			bkEdges[0].nextObj = &bkEdges[1];
			bkEdges[1].nextObj = 0;
			
			SPOINT pt1, pt2;
			CURVE c;
			pt1.y = raster.edgeClip.ymin;
			pt2.y = raster.edgeClip.ymax;

			pt1.x = pt2.x = raster.edgeClip.xmin;
			CurveSetLine(&pt1, &pt2, &c);
			bkEdges[0].Set(&c);

			pt1.x = pt2.x = raster.edgeClip.xmax;
			CurveSetLine(&pt1, &pt2, &c);
			bkEdges[1].Set(&c);

			bkEdges[0].dir 		= bkEdges[1].dir      = 0;
			bkEdges[0].fillRule = bkEdges[1].fillRule = fillEvenOddRule;
			bkEdges[0].color1 	= bkEdges[1].color1   = &bkColor;
			bkEdges[0].color2 	= bkEdges[1].color2   = 0;

			raster.AddEdges(bkEdges, &bkColor);
		} else {
			// It's transparent...
			raster.getBackground = true;
		}

		{
			// Add the object edges
			root.Draw(&raster, camera);
		}

#ifndef DISABLE_TAB_FOCUS
		// Add button focus rectangle
		RColor yellow;
		REdge* edges = NULL;

		if (useFocusRect && !RectIsEmpty(&tabFocusRect)) {
			// Set up the color
			yellow.SetUp(&raster);
			yellow.order = 0;
			yellow.rgb.alpha = 255;
			yellow.rgb.red   = 255;
			yellow.rgb.green = 255;
			yellow.rgb.blue  = 0;
			yellow.BuildCache();

			SRECT bounds = tabFocusRect;
			MATRIX mat;
			MatrixIdentity(&mat);

			int border = 3;
			if (antialias) {
				border *= 4;
			}

			SRECT rect = bounds;
			rect.xmax = bounds.xmin + border;
			AddRect(&rect, &mat, &yellow, this, &edges, NULL);

			rect.xmin = bounds.xmax - border;
			rect.xmax = bounds.xmax;
			AddRect(&rect, &mat, &yellow, this, &edges, NULL);

			rect.xmin = bounds.xmin;
			rect.ymax = bounds.ymin + border;
			AddRect(&rect, &mat, &yellow, this, &edges, NULL);

			rect.ymin = bounds.ymax - border;
			rect.ymax = bounds.ymax;
			AddRect(&rect, &mat, &yellow, this, &edges, NULL);

			raster.AddEdges(edges, &yellow);
		}
#endif
			
		raster.PaintBits();

#ifndef DISABLE_TAB_FOCUS
		if (!RectIsEmpty(&tabFocusRect)) {
			// Free the edges
			REdge* e = edges;
			while ( e ) {
				REdge* next = e->nextObj;
				FreeEdge(e);
				e = next;
			}
			edges = 0;
			yellow.FreeCache();
		}
#endif

		if ( backgroundColor.all != 0 ) 
			bkColor.FreeCache();

		bits->UnlockBits();
	}
}
Exemple #8
0
/**
 * Renders the text data into painter paths.
 */
void RTextRenderer::render() {
    boundingBox = RBox();
    painterPaths.clear();
    richText = "";

    QString text = textData.getEscapedText();
    //RVector position = textData.getPosition();
    RVector position = textData.getAlignmentPoint();
    double textHeight = textData.getTextHeight();
    RS::VAlign verticalAlignment = textData.getVAlign();
    RS::HAlign horizontalAlignment = textData.getHAlign();
    double lineSpacingFactor = textData.getLineSpacingFactor();
    QString fontName = textData.getFontName();
    bool bold = textData.isBold();
    bool italic = textData.isItalic();
    double angle = textData.getAngle();
    //RColor color = textData.getColor(true);

    // split up text where separation is required due to line feed,
    // or any type of height change (\P, \H[0-9]*.?[0-9]+;, \S*/*;)

    // split up text at every formatting change:
    QRegExp regExpAll(rxAll);
    QStringList literals = text.split(regExpAll);

    // collect formatting change information for every literal:
    QStringList formattings;
    int pos = 0;
    while ((pos = regExpAll.indexIn(text, pos)) != -1) {
        formattings << regExpAll.cap(1);
        pos += regExpAll.matchedLength();
    }

    // x position in real units:
    double xCursor = 0.0;
    // y position for next text line:
    double yCursor = 0.0;
    // painter paths for current text line:
    QList<RPainterPath> linePaths;
    // max ascent of current text line:
    double maxAscent = 0.0;
    // max descent of current line:
    double minDescent = 0.0;
    // max descent of _previous_ line:
    double minDescentPrevious = 0.0;
    // true for the first block of the current line:
    bool firstBlockInLine = true;
    // current line has leading spaces:
    bool leadingSpaces = false;
    // current line has trailing spaces:
    bool trailingSpaces = false;
    // text has leading empty lines:
    bool leadingEmptyLines = false;
    // text has trailing empty lines:
    bool trailingEmptyLines = false;
    int lineCounter = 0;
    QString textBlock;
    QList<QTextLayout::FormatRange> formats;

    bool blockChangedHeightOrFont = false;

    // implicit top level format block:
    QTextCharFormat f;
    f.setForeground(QBrush(QColor()));
    currentFormat.push(f);
    QTextLayout::FormatRange fr;
    fr.start = 0;
    fr.length = 0;
    fr.format = currentFormat.top();
    formats.append(fr);
    blockHeight.push(textHeight);
    blockFont.push(fontName);
    blockBold.push(bold);
    blockItalic.push(italic);
    useCadFont.push(RFontList::isCadFont(fontName));
    openTags.push(QStringList());

    width = 0.0;
    height = 0.0;

    // iterate through all text blocks:
    for (int i=0; i<literals.size(); ++i) {

        // the literal text, e.g. "ABC":
        QString literal = literals.at(i);

        // the formatting _after_ the text, e.g. "\C1;"
        QString formatting;
        if (i<formattings.size()) {
            formatting = formattings.at(i);
        }

//        qDebug() << "block: " << i;
//        qDebug() << "  literal: " << literal;
//        qDebug() << "  literal length: " << literal.length();
//        qDebug() << "  formatting: " << formatting;
//        qDebug() << "  font: " << blockFont.top();
//        qDebug() << "  height: " << blockHeight.top();
//        qDebug() << "  cad font: " << useCadFont.top();
//        qDebug() << "  xCursor: " << xCursor;

        // handle literal:
        textBlock.append(literal);

        if (firstBlockInLine) {
            if (!literal.isEmpty()) {
                if (literal.at(0).isSpace()) {
                    leadingSpaces = true;
                }
            }
            else {
                if (formatting=="\\~") {
                    leadingSpaces = true;
                }
            }
            firstBlockInLine = false;
        }

        bool lineFeed = false;
        bool paragraphFeed = false;
        bool heightChange = false;
        bool stackedText = false;
        bool fontChange = false;
        bool colorChange = false;
        bool blockEnd = false;

        // detect formatting that ends the current text block:
        if (!formatting.isEmpty()) {
            fontChange = QRegExp(rxFontChangeTtf).exactMatch(formatting) ||
                QRegExp(rxFontChangeCad).exactMatch(formatting);
            colorChange = QRegExp(rxColorChangeCustom).exactMatch(formatting) ||
                QRegExp(rxColorChangeIndex).exactMatch(formatting);
            heightChange = QRegExp(rxHeightChange).exactMatch(formatting);
            stackedText = QRegExp(rxStackedText).exactMatch(formatting);
            lineFeed = QRegExp(rxLineFeed).exactMatch(formatting);
            paragraphFeed = QRegExp(rxParagraphFeed).exactMatch(formatting);
            blockEnd = QRegExp(rxEndBlock).exactMatch(formatting);
        }

        bool start = (i==0);
        bool end = (i==literals.size()-1);

        // first line is empty:
        if (textBlock.trimmed().isEmpty() && (lineFeed || paragraphFeed || end)) {
            if (start) {
                leadingEmptyLines = true;
            }
            else if (end) {
                trailingEmptyLines = true;
            }
        }

        // reached a new text block that needs to be rendered separately
        // due to line feed, height change, font change, ...:
        if (target==RichText ||
            lineFeed || paragraphFeed || heightChange || stackedText ||
            fontChange || colorChange || end
            || (blockEnd && blockChangedHeightOrFont)) {

            // render block _before_ format change that requires new block:
            if (textBlock!="") {
                // fix format lengths to match up. each format stops where
                // the next one starts. formatting that is carried over is set
                // again for the new format.
                for (int i=0; i<formats.size(); i++) {
                    int nextStart;
                    if (i<formats.size()-1) {
                        nextStart = formats[i+1].start;
                    }
                    else {
                        nextStart = textBlock.length();
                    }
                    formats[i].length = nextStart - formats[i].start;
                }

                if (target==RichText) {
                    richText += getRichTextForBlock(
                                   textBlock, formats);
                }

                if (target==PainterPaths) {
                    double horizontalAdvance = 0.0;
                    double horizontalAdvanceNoSpacing = 0.0;
                    double ascent = 0.0;
                    double descent = 0.0;
                    QList<RPainterPath> paths;

                    // get painter paths for current text block at height 1.0:
                    paths = getPainterPathsForBlock(
                                textBlock, formats,
                                horizontalAdvance,
                                horizontalAdvanceNoSpacing,
                                ascent, descent);

                    // transform to scale text from 1.0 to current text height:
                    QTransform sizeTransform;
                    sizeTransform.scale(blockHeight.top(), blockHeight.top());

                    // transform for current block due to xCursor position:
                    QTransform blockTransform;
                    blockTransform.translate(xCursor, 0);

                    // combine transforms for current text block:
                    QTransform allTransforms = sizeTransform;
                    allTransforms *= blockTransform;

                    maxAscent = qMax(maxAscent, ascent * blockHeight.top());
                    minDescent = qMin(minDescent, descent * blockHeight.top());

                    // transform paths of current block and append to paths
                    // of current text line:
                    for (int i=0; i<paths.size(); ++i) {
                        RPainterPath p = paths.at(i);
                        p.transform(allTransforms);
                        linePaths.append(p);
                    }

                    xCursor += horizontalAdvance * blockHeight.top();
                }
            }

            // empty text, might be line feed, we need ascent, descent anyway:
            else if (lineFeed || paragraphFeed || end) {
                if (target==PainterPaths) {
                    double horizontalAdvance = 0.0;
                    double horizontalAdvanceNoSpacing = 0.0;
                    double ascent = 0.0;
                    double descent = 0.0;

                    // get painter paths for current text block at height 1.0:
                    getPainterPathsForBlock(
                                "A", QList<QTextLayout::FormatRange>(),
                                horizontalAdvance,
                                horizontalAdvanceNoSpacing,
                                ascent, descent);

                    maxAscent = qMax(maxAscent, ascent * blockHeight.top());
                    minDescent = qMin(minDescent, descent * blockHeight.top());
                }
            }

            // handle stacked text:
            if (stackedText) {
                QRegExp reg;
                reg.setPattern(rxStackedText);
                reg.exactMatch(formatting);

                if (target==PainterPaths) {
                    double horizontalAdvance[2];
                    horizontalAdvance[0] = 0.0;
                    horizontalAdvance[1] = 0.0;
                    double horizontalAdvanceNoSpacing[2];
                    horizontalAdvanceNoSpacing[0] = 0.0;
                    horizontalAdvanceNoSpacing[1] = 0.0;
                    double heightFactor = 0.4;

                    // s==0: superscript, s==1: subscript:
                    for (int s=0; s<=1; ++s) {
                        QString script = reg.cap(s+1);

                        QList<RPainterPath> paths;

                        double ascent = 0.0;
                        double descent = 0.0;

                        QList<QTextLayout::FormatRange> localFormats;

                        QTextLayout::FormatRange fr;
                        fr.start = 0;
                        fr.length = script.length();
                        fr.format = currentFormat.top();
                        localFormats.append(fr);

                        // get painter paths for superscript at height 1.0:
                        paths = getPainterPathsForBlock(
                                    script, localFormats,
                                    horizontalAdvance[s],
                                    horizontalAdvanceNoSpacing[s],
                                    ascent, descent);

                        if (s==0) {
                            maxAscent = qMax(maxAscent, ascent * blockHeight.top() * heightFactor + blockHeight.top()*(1.0-heightFactor));
                        }
                        else {
                            minDescent = qMin(minDescent, descent * blockHeight.top() * heightFactor);
                        }

                        // transform to scale text from 1.0 to current text height * 0.4:
                        QTransform sizeTransform;
                        sizeTransform.scale(blockHeight.top()*heightFactor, blockHeight.top()*heightFactor);

                        // move top text more to the right for italic texts:
                        double xOffset = 0.0;
                        if (s==0 && blockItalic.top()==true) {
                            double y = blockHeight.top()*(1.0-heightFactor);
                            // assume italic means roughly 12 degrees:
                            xOffset = tan(RMath::deg2rad(12)) * y;
                        }

                        // transform for current block due to xCursor position
                        // and top or bottom text position:
                        QTransform blockTransform;
                        blockTransform.translate(xCursor + xOffset,
                                                 s==0 ? blockHeight.top()*(1.0-heightFactor) : 0.0);

                        horizontalAdvance[s] += xOffset / (blockHeight.top() * heightFactor);

                        // combine transforms for current text block:
                        QTransform allTransforms = sizeTransform;
                        allTransforms *= blockTransform;

                        // transform paths of current block and append to paths
                        // of current text line:
                        for (int i=0; i<paths.size(); ++i) {
                            RPainterPath p = paths.at(i);
                            p.transform(allTransforms);
                            linePaths.append(p);
                        }
                    }

                    xCursor += qMax(horizontalAdvance[0], horizontalAdvance[1]) * blockHeight.top() * heightFactor;
                }

                if (target==RichText) {
                    QString super = reg.cap(1);
                    QString sub = reg.cap(2);
                    if (!super.isEmpty()) {
                        richText += QString("<span style=\"vertical-align:super;\">%1</span>").arg(super);
                    }
                    if (!sub.isEmpty()) {
                        richText += QString("<span style=\"vertical-align:sub;\">%1</span>").arg(sub);
                    }
                }
            }

            // prepare for next text block:
            if (lineFeed || paragraphFeed || end) {
                if (!textBlock.isEmpty()) {
                    if (textBlock.at(textBlock.length()-1).isSpace()) {
                        trailingSpaces = true;
                    }
                }
//                else {
//                    if (formatting=="\\~") {
//                        trailingSpaces = true;
//                    }
//                }
            }

            textBlock = "";
            formats.clear();
            QTextLayout::FormatRange fr;
            fr.start = 0;
            fr.length = 0;
            fr.format = currentFormat.top();
            formats.append(fr);

            // handle text line.
            // add all painter paths of the current line to result set of
            // painter paths. apply line feed transformations.
            if (lineFeed || paragraphFeed || end) {
//                qDebug() << "lineFeed: adding text line:";
//                qDebug() << "  maxAscent: " << maxAscent;
//                qDebug() << "  minDescent: " << minDescent;
//                qDebug() << "  minDescentPrevious: " << minDescentPrevious;
//                qDebug() << "got line feed or end";
//                qDebug() << "  trailingSpaces: " << trailingSpaces;

                if (target==RichText) {
                    if (lineFeed || paragraphFeed) {
                        richText += "<br/>";
                    }
                }

                if (lineCounter!=0) {
                    yCursor += (minDescentPrevious - maxAscent) * lineSpacingFactor;
                }

                // calculate line bounding box for alignment without spaces at borders:
                RBox lineBoundingBox;
                for (int i=0; i<linePaths.size(); ++i) {
                    RPainterPath p = linePaths.at(i);
                    lineBoundingBox.growToInclude(p.getBoundingBox());
                }

                double featureSize = lineBoundingBox.getHeight();

                QTransform lineTransform;

                switch (horizontalAlignment) {
                case RS::HAlignAlign:
                case RS::HAlignFit:
                case RS::HAlignLeft:
                    if (!leadingSpaces) {
                        // move completely to the left (left border is 0.0):
                        lineTransform.translate(
                                    -lineBoundingBox.getMinimum().x,
                                    yCursor);
                    }
                    else {
                        lineTransform.translate(0, yCursor);
                    }
                    break;
                case RS::HAlignMid:
                case RS::HAlignCenter:
                    if (!leadingSpaces && !trailingSpaces) {
                        lineTransform.translate(
                                    -(lineBoundingBox.getMinimum().x +
                                      lineBoundingBox.getMaximum().x)/2.0,
                                    yCursor);
                    }
                    else {
                        lineTransform.translate(-xCursor/2.0, yCursor);
                    }
                    break;
                case RS::HAlignRight:
                    if (!trailingSpaces) {
                        lineTransform.translate(-lineBoundingBox.getMaximum().x, yCursor);
                    }
                    else {
                        lineTransform.translate(-xCursor, yCursor);
                    }
                    break;
                }

                width = qMax(width, lineBoundingBox.getMaximum().x - qMin(0.0, lineBoundingBox.getMinimum().x));

                // add current text line to result set:
                QPen pen;
                for (int i=0; i<linePaths.size(); ++i) {
                    RPainterPath p = linePaths[i];
                    if (i==0) {
                        pen = p.getPen();
                        if (pen.style()==Qt::NoPen) {
                           pen = QPen(p.getBrush().color());
                        }
                    }
                    p.transform(lineTransform);
                    p.setFeatureSize(featureSize);
                    painterPaths.append(p);
                    boundingBox.growToInclude(p.getBoundingBox());
                }

                RPainterPath bbPath;
                bbPath.addBox(lineBoundingBox);
                bbPath.transform(lineTransform);
                bbPath.setFeatureSize(-featureSize);
                bbPath.setPen(pen);
                painterPaths.append(bbPath);

                lineCounter++;
                xCursor = 0.0;
                maxAscent = 0.0;
                minDescentPrevious = minDescent;
                minDescent = 0.0;
                linePaths.clear();
                firstBlockInLine = true;
                leadingSpaces = false;
                trailingSpaces = false;
            }
        }

        // handle formatting after text block, that applies either
        // to the next text block(s) or the rest of the current text block:
        if (formatting.isEmpty()) {
            continue;
        }

        QRegExp reg;

        // unicode:
        reg.setPattern(rxUnicode);
        if (reg.exactMatch(formatting)) {
            textBlock += QChar(reg.cap(1).toInt(0, 16));
            continue;
        }

        // curly braket open:
        reg.setPattern(rxCurlyOpen);
        if (reg.exactMatch(formatting)) {
            textBlock += "{";
            continue;
        }

        // curly braket close:
        reg.setPattern(rxCurlyClose);
        if (reg.exactMatch(formatting)) {
            textBlock += "}";
            continue;
        }

        // degree:
        reg.setPattern(rxDegree);
        if (reg.exactMatch(formatting)) {
            textBlock += chDegree;
            continue;
        }

        // plus/minus:
        reg.setPattern(rxPlusMinus);
        if (reg.exactMatch(formatting)) {
            textBlock += chPlusMinus;
            continue;
        }

        // diameter:
        reg.setPattern(rxDiameter);
        if (reg.exactMatch(formatting)) {
            textBlock += chDiameter;
            continue;
        }

        // backslash:
        reg.setPattern(rxBackslash);
        if (reg.exactMatch(formatting)) {
            textBlock += "\\";
            continue;
        }

        // non-breaking space:
        reg.setPattern(rxNonBreakingSpace);
        if (reg.exactMatch(formatting)) {
            if (target==PainterPaths) {
                textBlock += QChar(Qt::Key_nobreakspace);
            }
            if (target==RichText) {
                textBlock += "&nbsp;";
            }
            continue;
        }

        // font change (TTF):
        reg.setPattern(rxFontChangeTtf);
        if (reg.exactMatch(formatting)) {
            blockFont.top() = reg.cap(1);
            blockBold.top() = (reg.cap(2).toInt()!=0);
            blockItalic.top() = (reg.cap(3).toInt()!=0);
            useCadFont.top() = false;
            blockChangedHeightOrFont = true;

            if (target==RichText) {
                QString style;
                style += QString("font-family:%1;").arg(blockFont.top());
                style += QString("font-weight:%1;").arg(blockBold.top() ? "bold" : "normal");
                style += QString("font-style:%1;").arg(blockItalic.top() ? "italic" : "normal");
                richText += QString("<span style=\"%1\">").arg(style);
                openTags.top().append("span");
            }
            continue;
        }

        // font change (CAD):
        reg.setPattern(rxFontChangeCad);
        if (reg.exactMatch(formatting)) {
            blockFont.top() = reg.cap(1);
            useCadFont.top() = true;
            if (xCursor>RS::PointTolerance) {
                RFont* f = RFontList::get(blockFont.top());
                if (f!=NULL && f->isValid()) {
                    xCursor += f->getLetterSpacing() / 9.0;
                }
            }
            blockChangedHeightOrFont = true;

            if (target==RichText) {
                QString style;
                style += QString("font-family:%1;").arg(blockFont.top());
                richText += QString("<span style=\"%1\">").arg(style);
                openTags.top().append("span");
            }
            continue;
        }

        // height change:
        reg.setPattern(rxHeightChange);
        if (reg.exactMatch(formatting)) {
            bool factor = reg.cap(2)=="x";

            if (factor) {
                blockHeight.top() *= reg.cap(1).toDouble();
            }
            else {
                blockHeight.top() = reg.cap(1).toDouble();
            }
            blockChangedHeightOrFont = true;

            if (target==RichText) {
                QString style;
                style += QString("font-size:%1pt;").arg(blockHeight.top() * fontHeightFactor);
                richText += QString("<span style=\"%1\">").arg(style);
                openTags.top().append("span");
            }
            continue;
        }

        QTextLayout::FormatRange fr;
        fr.start = textBlock.length();
        fr.length = 0;

        // start format block:
        reg.setPattern(rxBeginBlock);
        if (reg.exactMatch(formatting)) {
            currentFormat.push(currentFormat.top());
            blockFont.push(blockFont.top());
            blockBold.push(blockBold.top());
            blockItalic.push(blockItalic.top());
            blockHeight.push(blockHeight.top());
            useCadFont.push(useCadFont.top());
            if (target==RichText) {
                openTags.push(QStringList());
            }
            blockChangedHeightOrFont = false;
            continue;
        }

        // end format block:
        reg.setPattern(rxEndBlock);
        if (reg.exactMatch(formatting)) {
            currentFormat.pop();
            fr.format = currentFormat.top();
            formats.append(fr);
            blockFont.pop();
            blockBold.pop();
            blockItalic.pop();
            blockHeight.pop();
            useCadFont.pop();
            blockChangedHeightOrFont = false;

            if (target==RichText) {
                // close all tags that were opened in this block:
                for (int i=openTags.top().size()-1; i>=0; --i) {
                    QString tag = openTags.top().at(i);
                    richText += QString("</%1>").arg(tag);
                }
                openTags.pop();
            }

            continue;
        }

        // color change (indexed):
        reg.setPattern(rxColorChangeIndex);
        if (reg.exactMatch(formatting)) {
            RColor blockColor = RColor::createFromCadIndex(reg.cap(1));
            if (blockColor.isByLayer()) {
                currentFormat.top().setForeground(RColor::CompatByLayer);
            } else if (blockColor.isByBlock()) {
                currentFormat.top().setForeground(RColor::CompatByBlock);
            }
            else {
                currentFormat.top().setForeground(blockColor);
            }
            fr.format = currentFormat.top();
            formats.append(fr);

            if (target==RichText) {
                QString style;
                style += QString("color:%1;").arg(blockColor.name());
                richText += QString("<span style=\"%1\">").arg(style);
                openTags.top().append("span");
            }
            continue;
        }

        // color change (custom):
        reg.setPattern(rxColorChangeCustom);
        if (reg.exactMatch(formatting)) {
            RColor blockColor = RColor::createFromCadCustom(reg.cap(1));
            currentFormat.top().setForeground(blockColor);
            fr.format = currentFormat.top();
            formats.append(fr);

            if (target==RichText) {
                QString style;
                style += QString("color:%1;").arg(blockColor.name());
                richText += QString("<span style=\"%1\">").arg(style);
                openTags.top().append("span");
            }
            continue;
        }
    }

    if (target==PainterPaths) {
        // at this point, the text is at 0/0 with the base line of the
        // first text line at y==0

        // vertical alignment:
        double topLine = qMax(textHeight, boundingBox.getMaximum().y);
        double bottomLine = qMin(0.0, boundingBox.getMinimum().y);

        QTransform globalTransform;
        globalTransform.translate(position.x, position.y);
        globalTransform.rotate(RMath::rad2deg(angle));
        switch (verticalAlignment) {
        case RS::VAlignTop:
            //if (!leadingEmptyLines) {
                globalTransform.translate(0.0, -topLine);
            //}
            break;
        case RS::VAlignMiddle:
            if (leadingEmptyLines || trailingEmptyLines) {
                globalTransform.translate(0.0, -(yCursor+textHeight)/2.0);
            }
            else {
                globalTransform.translate(0.0, -(bottomLine + topLine) / 2.0);
            }
            break;
        case RS::VAlignBottom:
        case RS::VAlignBase:
            if (trailingEmptyLines) {
                globalTransform.translate(0.0, -yCursor);
            }
            else {
                globalTransform.translate(0.0, -bottomLine);
            }
            break;
        }

        height = boundingBox.getHeight();

        // apply global transform for position, angle and vertical alignment:
        boundingBox = RBox();
        for (int i=0; i<painterPaths.size(); ++i) {
            painterPaths[i].transform(globalTransform);
            boundingBox.growToInclude(painterPaths[i].getBoundingBox());
        }
    }

    if (target==RichText) {
        // close all tags that were opened:
        for (int i=openTags.top().size()-1; i>=0; --i) {
            QString tag = openTags.top().at(i);
            richText += QString("</%1>").arg(tag);
        }
    }
}
//****************************************************************************
//
// Function Name: FillData
//
// Description:   Fills an HeadlineDataStruct with the Headline 
//						depth effect data
//
// Returns:       None
//
// Exceptions:	   None
//
//****************************************************************************
void RHeadlineDepthPage::FillData( RHeadlineInterface* pInterface, RComponentView* pComponentView )
{
	//
	// Set the depth effects
	//

	if (m_data.nDataType == kShadowType)
	{
		// Clear any depth effects
		pInterface->SetProjectionEffect( kNoProjection ) ;

		RSoftShadowSettings settings;

		settings.m_fShadowOn           = TRUE;
		settings.m_fShadowOpacity      = m_data.nOpacity / 100.0;
		settings.m_fShadowEdgeSoftness = m_data.nEdgeSoftness  / 100.0;
		settings.m_fShadowOffset       = m_data.nOffset / 65535.0;

		settings.m_fShadowAngle = -m_wndBlendAngle.GetAngle();
		settings.m_fShadowColor = m_btnColor.GetColor().GetSolidColor();
		pComponentView->SetShadowSettings( settings );
	}
	else
	{
		if (pComponentView->HasShadow())
		{
			// Clear any shadow settings
			RSoftShadowSettings settings;
			pComponentView->GetShadowSettings( settings );
			settings.m_fShadowOn = FALSE;

			pComponentView->SetShadowSettings( settings );
		}

		RIntPoint ptVanish(
			int(cos(m_angle) * m_data.nVanishPointX + 0.5),
			int(sin(m_angle) * m_data.nVanishPointY + 0.5) ) ;

		pInterface->SetNumStages( m_data.nNumStages ) ;
		pInterface->SetProjectionEffect( (EProjectionEffects) m_data.nSelProjection ) ;
		pInterface->SetProjectionDepth( m_data.flDepth ) ;
		pInterface->SetProjectionVanishPoint( ptVanish ) ;
		pInterface->SetProjectionFillColor( m_btnColor.GetColor() ) ;

		pInterface->SetShadowEffect( (EShadowEffects) m_data.nSelShadow ) ;
		pInterface->SetShadowDepth( m_data.flDepth ) ;
		pInterface->SetShadowVanishPoint( ptVanish ) ;
		pInterface->SetShadowFillColor( m_btnColor.GetColor() ) ;

		if (m_data.fBlend && m_data.nSelProjection > kNoProjection)
		{
	//		EFramedEffects eFrameEffect ;
	//		pInterface->GetBehindEffect( eFrameEffect ) ;

			RColor crBlendColor ;
			pInterface->GetBehindColor( crBlendColor ) ;

			if (RColor::kTransparent == crBlendColor.GetFillMethod())
			{
				crBlendColor = RSolidColor( kWhite ) ;
			}

			RSolidColor crBlendArray[] = 	{ 
				m_btnColor.GetColor().GetSolidColor(),
				crBlendColor.GetSolidColor() } ;

			crBlendColor = RColor( crBlendArray, 2, m_angle ) ;
			pInterface->SetProjectionFillColor( crBlendColor ) ;
		}
	}

	if (m_data.nSelProjection > kNoProjection || m_data.nDataType == kShadowType)
	{
		EOutlineEffects eOutlineEffect ;
		pInterface->GetOutlineEffect( eOutlineEffect ) ;

		//
		// The user selected a depth option which is mutually exclusive 
		// with the emboss and deboss outline options, so we need to clear 
		// the emboss/deboss option if it is set.
		//
		switch (eOutlineEffect)
		{
		case kEmbossedOutline: 
		case kDebossedOutline:
		case kBlurredOutline:
			{
//				RColor crBehindColor ;
//				pInterface->GetBehindColor( crBehindColor ) ;
//				EFramedEffects eFrameEffect = (RColor::kTransparent == 
//					crBehindColor.GetFillMethod() ? kFrameNoFrame : kSimpleFrame) ;

				// Clear the outline effect
				pInterface->SetOutlineEffect( kSimpleFill ) ;

				// Set the appropriate behind effect.
//				pInterface->SetBehindEffect( eFrameEffect ) ;
			}
		}
	}
}
//****************************************************************************
//
// Function Name: ApplyData
//
// Description:   Applies HeadlineDataStruct effect's data
//                to the Headline depth controls
//
// Returns:       None
//
// Exceptions:	   None
//
//****************************************************************************
void RHeadlineDepthPage::ApplyData( RHeadlineInterface* pInterface, RComponentView* pComponentView )
{
	// Set the effects data
	//////////////////////////

	EProjectionEffects eProjEffects ;
	EShadowEffects eShadowEffects ;
	RIntPoint ptVanish ;
	RColor crFillColor ;
	int nNumStages ;


	pInterface->GetNumStages( nNumStages ) ;
	pInterface->GetProjectionEffect( eProjEffects ) ;
	pInterface->GetProjectionDepth( m_data.flDepth ) ;
	pInterface->GetShadowEffect( eShadowEffects ) ;
	pInterface->GetProjectionFillColor( crFillColor ) ;
	pInterface->GetProjectionVanishPoint( ptVanish ) ;

	if (eShadowEffects > kNoShadow)
	{
		// Currently these options are shared, but in
		// pre-existing data they may not be.
		pInterface->GetShadowFillColor( crFillColor ) ;
		pInterface->GetShadowVanishPoint( ptVanish ) ;
	}

	if (pComponentView->HasShadow())
	{
		RSoftShadowSettings settings;
		pComponentView->GetShadowSettings( settings );

		m_data.nDataType      = kShadowType;
		m_data.nOpacity       = ::Round( settings.m_fShadowOpacity * 100 );
		m_data.nEdgeSoftness  = ::Round( settings.m_fShadowEdgeSoftness * 100 );
		m_data.nOffset        = ::Round( settings.m_fShadowOffset * 65535 );

		m_wndBlendAngle.SetAngle( -settings.m_fShadowAngle );
		m_angle = m_wndBlendAngle.GetAngle();

		m_btnColor.SetColor( RColor( settings.m_fShadowColor ) ) ;
	}
	else
	{
		m_data.nDataType      = kDepthType ;
		m_data.nNumStages     = nNumStages ;
		m_data.nSelProjection = eProjEffects ;
		m_data.nSelShadow     = eShadowEffects ;
		m_data.fBlend			 = sWORD( RColor::kGradient == crFillColor.GetFillMethod() ) ;

		m_wndBlendAngle.SetAngle( atan2( YRealDimension( ptVanish.m_y ), 
			YRealDimension( ptVanish.m_x ) ) ) ;

		m_btnColor.SetColor( RColor(crFillColor.GetSolidColor()) ) ;

		m_angle = m_wndBlendAngle.GetAngle()  ;

		YAngle angle = fmod((double)m_angle, (double)(2.0 * kPI));
		if (angle < 0.0) angle += 2.0 * kPI;
		const YRealDimension kAngleDelta = 0.00001;
		
		if (::AreFloatsEqual(angle, kPI / 2.0, kAngleDelta) || ::AreFloatsEqual(angle, 3.0 * kPI / 2.0, kAngleDelta))
			m_data.nVanishPointX = 0;
		else
			m_data.nVanishPointX = ptVanish.m_x / cos( m_angle ) ;
		
		if (::AreFloatsEqual(angle, 0.0, kAngleDelta) || ::AreFloatsEqual(angle, kPI, kAngleDelta))
			m_data.nVanishPointY = 0;
		else
			m_data.nVanishPointY = ptVanish.m_y / sin( m_angle ) ;

/*		if (m_data.nSelShadow > kNoShadow)
		{
			pInterface->GetShadowDepth( m_data.flDepth ) ;

			m_data.nDataType      = kShadowType;
			m_data.nOpacity       = 100;
			m_data.nEdgeSoftness  = 0;
			m_data.nOffset        = 10; // TODO: determine from vanishing point

			FillData( pInterface, pComponentView );
		}
*/	}


	if (GetSafeHwnd())
	{
		// Set the image selection
		EnumResourceNames( 
			AfxGetResourceHandle(),				// resource-module handling
			cResourceType,							// pointer to resource type 
			(ENUMRESNAMEPROC) SelectResItem,	// pointer to callback function 
			(LONG) this ) ; 						// application-defined parameter 

		m_btnColor.EnableWindow( m_gcImageList.GetCurSel() != 0 ) ;
	}
}
Exemple #11
0
/**
 * \return Highlighted color for the given color.
 */
RColor RColor::getHighlighted(const RColor& color, const QColor& bgColor, int minDist) {
    if (!color.isValid()) {
        return Qt::gray;
    }

    RColor ret = color;

    int vColor = color.value();
    int vBgColor = bgColor.value();

    // 0     vColor                      vBgColor              255
    // |--------^----------------------------^------------------|
    // |<--d1-->|<------------d2------------>|<-------d3------->|
    int d1 = qMin(vColor, vBgColor);
    //int d2 = qAbs(vColor - vBgColor);
    int d3 = 255 - qMax(vColor, vBgColor);

    // d3 is big enough: set value to max (highlight):
    if (d3>=minDist) {
        ret.setHsv(color.hue(), color.saturation(), 255);
    }

    // d1 is big enough: set value to half (lowlight):
    else if (d1>=minDist) {
        ret.setHsv(color.hue(), color.saturation(), qMin(vColor, vBgColor)/2);
    }

    // black on white:
    else if (vColor<32 && vBgColor>224) {
        ret.setHsv(color.hue(), color.saturation(), 160);
    }

    // d2 is the only significant distance, set value to medium:
    else if (vColor<vBgColor) {
        ret.setHsv(color.hue(), color.saturation(), qMin(vColor+minDist, 255));
    }
    else {
        ret.setHsv(color.hue(), color.saturation(), qMax(vColor-minDist, 0));
    }

    return ret;
}
Exemple #12
0
bool RColor::operator<(const RColor & color) const {
    return getHash() < color.getHash();
}