void WCartesianChart::drawMarker(const WDataSeries& series, WPainterPath& result) const { const double size = 6.0; const double hsize = size/2; switch (series.marker()) { case CircleMarker: result.addEllipse(-hsize, -hsize, size, size); break; case SquareMarker: result.addRect(WRectF(-hsize, -hsize, size, size)); break; case CrossMarker: result.moveTo(-1.3 * hsize, 0); result.lineTo(1.3 * hsize, 0); result.moveTo(0, -1.3 * hsize); result.lineTo(0, 1.3 * hsize); break; case XCrossMarker: result.moveTo(-hsize, -hsize); result.lineTo(hsize, hsize); result.moveTo(-hsize, hsize); result.lineTo(hsize, -hsize); break; case TriangleMarker: result.moveTo( 0, 0.6 * hsize); result.lineTo(-hsize, 0.6 * hsize); result.lineTo(0, -hsize); result.lineTo(hsize, 0.6 * hsize); result.closeSubPath(); break; case CustomMarker: result = series.customMarker(); break; default: ; } }
void WPainter::drawText(const WRectF& rectangle, WFlags<AlignmentFlag> alignmentFlags, TextFlag textFlag, const WString& text) { if (textFlag == TextSingleLine) drawText(rectangle, alignmentFlags, text); else { if (!(alignmentFlags & AlignVerticalMask)) alignmentFlags |= AlignTop; if (!(alignmentFlags & AlignHorizontalMask)) alignmentFlags |= AlignLeft; if (device_->features() & WPaintDevice::CanWordWrap) device_->drawText(rectangle.normalized(), alignmentFlags, textFlag, text); else if (device_->features() & WPaintDevice::HasFontMetrics) { #ifndef WT_TARGET_JAVA MultiLineTextRenderer renderer(*this, rectangle); AlignmentFlag horizontalAlign = alignmentFlags & AlignHorizontalMask; AlignmentFlag verticalAlign = alignmentFlags & AlignVerticalMask; /* * Oh irony: after all these years of hating CSS, we now * implemented an XHTML renderer for which we need to use the * same silly workarounds to render the text with all possible * alignment options */ WStringStream s; s << "<table style=\"width:" << (int)rectangle.width() << "px;\"" "cellspacing=\"0\"><tr>" "<td style=\"padding:0px;height:" << (int)rectangle.height() << "px;color:" << pen().color().cssText() << ";text-align:"; switch (horizontalAlign) { case AlignLeft: s << "left"; break; case AlignRight: s << "right"; break; case AlignCenter: s << "center"; break; default: break; } s << ";vertical-align:"; switch (verticalAlign) { case AlignTop: s << "top"; break; case AlignBottom: s << "bottom"; break; case AlignMiddle: s << "middle"; break; default: break; } s << ";" << font().cssText(false); s << "\">" << WWebWidget::escapeText(text, true).toUTF8() << "</td></tr></table>"; save(); /* * FIXME: what if there was already a clip path? We need to combine * them ... */ WPainterPath p; p.addRect(rectangle.x() + 1, rectangle.y() + 1, rectangle.width() - 2, rectangle.height() - 2); setClipPath(p); setClipping(true); renderer.render(WString::fromUTF8(s.str())); restore(); #endif // WT_TARGET_JAVA } else throw WException("WPainter::drawText(): device does not support " "TextWordWrap or FontMetrics"); } }
void WStandardColorMap::paintLegend(WPainter *painter, const WRectF& area) const { painter->save(); WPainterPath clipPath; painter->setRenderHint(WPainter::Antialiasing, false); painter->setFont(labelFont_); int height; if (area.isNull()) { height = (int)painter->device()->height().value(); } else { clipPath.addRect(area); painter->setClipPath(clipPath); painter->setClipping(true); painter->translate(area.x(), area.y()); height = (int)area.height(); } int textHeight = (int)painter->font().sizeLength().toPixels(); // draw the colormap with a box around it int stripWidth = 50; createStrip(painter, WRectF(0, (int)(textHeight/2+0.5), (int)stripWidth, (int)(height-textHeight))); painter->setPen(WPen()); painter->setBrush(WBrush()); painter->drawRect(WRectF(0.5, (int)(textHeight/2) + 0.5, stripWidth, height-textHeight)); // draw the ticks + labels painter->translate(stripWidth, textHeight/2); if (continuous_) { int lineHeights = (int)(height/textHeight); int lhPerTick = 1 + tickSpacing_; int nbTicks = lineHeights % lhPerTick == 0 ? lineHeights/lhPerTick : lineHeights/lhPerTick + 1; int interval = (height-textHeight)/(nbTicks-1); int rest = (height-textHeight) % (nbTicks-1); int adjustedInterval = interval; double value = max_; double valDiff = (max_-min_)/(nbTicks-1); for (int i=0; i < nbTicks; i++) { painter->drawLine(0, 0.5, 4, 0.5); painter->drawText(10, -textHeight/2, 40, textHeight, AlignLeft | AlignMiddle, Wt::asString(value, format_)); value -= valDiff; if (rest > 0) { adjustedInterval = interval + 1; rest--; } else { adjustedInterval = interval; } painter->translate(0, adjustedInterval); } } else { // first paint tick for maximum value painter->drawLine(0, 0.5, 4, 0.5); painter->drawText(10, -textHeight/2, 100, textHeight, AlignLeft | AlignMiddle, Wt::asString(max_, format_)); // paint the rest of the ticks int nbTicks = colors_.size(); int prevDiff = 0; for (int i=nbTicks-1; i >= 0; i--) { double relPos = -(colors_[i].value()-max_)/(max_-min_); double diff = relPos*(height-textHeight); int roundedDiff = (int)(diff + 0.5); painter->translate(0, roundedDiff-prevDiff); painter->drawLine(0, 0.5, 4, 0.5); painter->drawText(10, -textHeight/2, 40, textHeight, AlignLeft | AlignMiddle, Wt::asString(colors_[i].value(), format_)); prevDiff = roundedDiff; } } painter->restore(); }