void GraphicsView::drawForeground(QPainter *painter, const QRectF &/*rect*/) { int height = 30; int textSize = 16; // Height of text bounding box, in pixels QBrush bg = QBrush(QColor::fromRgb(0, 0, 0, 200)); QPen text = QPen(QColor::fromRgb(220,220,0)); QFont font("Sans", 10); QString string("Drag to move. Scroll to zoom."); // We want to draw in viewport coordinates, so remove the painter // scaling, and move it into position height pixels above the // bottom. QRect vp = painter->viewport(); painter->setWorldTransform(QTransform(1.0, // scale x 0, 0, 1.0, // scale y 0, // x pos vp.height()-height)); // y pos // Draw the translucent rectangle in the bottom of the screen. Make // sure the border in the sides are outside the view (so there's a // border at the top only. QRect rect = QRect(-1, 0, vp.width()+2, height); painter->setBrush(bg); painter->drawPolygon(rect); painter->setPen(text); painter->setFont(font); int ypos = (height-textSize)/2; QRectF textPos(QPoint(10,ypos), QSize(vp.width(), height-ypos)); painter->drawText(textPos, Qt::AlignLeft, string); }
void CBattleConsole::showAll(SDL_Surface * to) { Point textPos(pos.x + pos.w/2, pos.y + 17); if(ingcAlter.size()) { graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(ingcAlter, pos.w, FONT_SMALL), Colors::WHITE, textPos); } else if(alterTxt.size()) { graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(alterTxt, pos.w, FONT_SMALL), Colors::WHITE, textPos); } else if(texts.size()) { if(texts.size()==1) { graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(texts[0], pos.w, FONT_SMALL), Colors::WHITE, textPos); } else { graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(texts[lastShown - 1], pos.w, FONT_SMALL), Colors::WHITE, textPos); textPos.y += 16; graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(texts[lastShown], pos.w, FONT_SMALL), Colors::WHITE, textPos); } } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void OverlayTextBox::render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size, bool software) { Mat4d ident; MatrixState matrixState(position, size, ident, ident); Vec2f textPos(0.0f, static_cast<float>(size.y())/2.0f); if (m_drawBorder || m_drawBackground) { renderBackgroundAndBorder(oglContext, position, size, software); textPos.x() = 4; // Allow for margin } Vec2ui textExtent = m_font->textExtent(m_text); textPos.y() -= (static_cast<float>(textExtent.y())/2.0f); // Set the text m_textDrawer->removeAllTexts(); m_textDrawer->addText(m_text, textPos); m_textDrawer->setTextColor(m_textColor); // Draw the text if (software) { m_textDrawer->renderSoftware(oglContext, matrixState); } else { m_textDrawer->render(oglContext, matrixState); } }
TextRun InlineTextBox::constructTextRun( const ComputedStyle& style, StringView string, int maximumLength, StringBuilder* charactersWithHyphen) const { if (charactersWithHyphen) { const AtomicString& hyphenString = style.hyphenString(); charactersWithHyphen->reserveCapacity(string.length() + hyphenString.length()); charactersWithHyphen->append(string); charactersWithHyphen->append(hyphenString); string = charactersWithHyphen->toString(); maximumLength = string.length(); } ASSERT(maximumLength >= static_cast<int>(string.length())); TextRun run(string, textPos().toFloat(), expansion(), expansionBehavior(), direction(), dirOverride() || style.rtlOrdering() == EOrder::Visual); run.setTabSize(!style.collapseWhiteSpace(), style.getTabSize()); run.setTextJustify(style.getTextJustify()); // Propagate the maximum length of the characters buffer to the TextRun, even // when we're only processing a substring. run.setCharactersLength(maximumLength); ASSERT(run.charactersLength() >= run.length()); return run; }
void Button::repaint() { QImage tmp(m_size, QImage::Format_ARGB32_Premultiplied); tmp.fill(0); { QPainter p(&tmp); p.setRenderHint(QPainter::Antialiasing); QPen pen(QColor(200, 200, 220, 255)); pen.setWidth(2); p.setPen(pen); p.setBrush(QBrush(QColor( static_cast<int>(m_brightness), static_cast<int>(m_brightness), static_cast<int>(m_brightness), 100))); p.drawRoundRect(1, 1, m_size.width() - 2, m_size.height() -2, 2000 / m_size.width(), 2000 / m_size.height()); p.drawPixmap(10, m_size.height() / 2 - 16, 32, 32, m_icon.pixmap(32, 32)); if (!m_editor) { p.setFont(m_font); p.drawText(textPos(), m_text); } } setPixmap(QPixmap::fromImage(tmp)); updateEditor(); }
void GameCompleteScreen::setup(sf::View view , int sheepHerded) { mBackground.setPosition(view.getCenter()); sf::Vector2f textPos(view.getCenter()); float fontSize = mTitleText.getCharacterSize(); textPos.y -= fontSize; mTitleText.setPosition(textPos); textPos.y += fontSize; mSheepStatText.setString("Sheep Herded " + std::to_string(sheepHerded)); sf::FloatRect bounds = mSheepStatText.getLocalBounds(); mSheepStatText.setOrigin(bounds.width / 2.f , 0.f); fontSize = mSheepStatText.getCharacterSize(); mSheepStatText.setPosition(textPos); textPos.y += fontSize; int inc = mMenuText.at(0).getCharacterSize(); textPos.y += inc; for(sf::Text& text : mMenuText) { text.setPosition(textPos); textPos.y += inc; } }
void Button::updateEditor() { if (m_editor) { const int SPACE = 9; m_editor->setGeometry(QRect(absolutePosition() + QPoint(textPos().x(), SPACE), QSize(m_size.width() - 10 - 10 - 32 - 10, m_size.height() - SPACE * 2))); } }
void DistanceMap::draw(CCBot & bot) const { const int tilesToDraw = 200; for (size_t i(0); i < tilesToDraw; ++i) { auto & tile = m_sortedTilePositions[i]; int dist = getDistance(tile); sc2::Point2D textPos(tile.x + 0.5f, tile.y + 0.5f); std::stringstream ss; ss << dist; bot.Map().drawText(textPos, ss.str()); } }
// --------------------------------------------------------------------------- // CSmileyModel::FindMatchStr // --------------------------------------------------------------------------- // TInt CSmileyModel::TryFindMatchNode( const TDesC& aText, TInt aTextPos ) { TInt index( 0 ); index = FindInSibling( index, aText[aTextPos] ); TInt textPos( aTextPos + 1 ); while ( index != KInvalidIndex && !IsFinalNode( index ) && textPos < aText.Length() ) { index = iStrArray[index].iChild; index = FindInSibling( index, aText[textPos] ); if ( index != KInvalidIndex ) { textPos++; } } return index; }
int ConfigFile::_ReadEntry(const char *entry, char *buf, int bufSize,bool strip ) { /* 功能:读取entry的值 参数: entry[IN]:entry名称 buf[IN]:存放entry的值的缓冲区 bufSize[IN]:缓冲区长度 strip[IN]:去除空格标志 返回值: 成功返回读取的长度 失败返回-1 */ char lineBuf[1024]; //memset(lineBuf,0,1024); char *p, *cur; int len; cur = buf; *cur = '\0'; len = -1; while(FGetS(lineBuf,1023,fin)) { if( isTitleLine( lineBuf ) ) // section fis ended break; p = textPos( lineBuf, entry ); // not equal this entry if( p == 0 ) continue; if( strip ) stripQuotationChar( p ); len = strlen(p); if( bufSize-1 < len ) len = bufSize-1; strncpy( cur, p, len ); cur[len] = 0; break; } return len; }
int InlineTextBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool& foundBox) { if (foundBox) { m_truncation = cFullTruncation; return -1; } int ellipsisX = ltr ? blockEdge - ellipsisWidth : blockEdge + ellipsisWidth; // For LTR, if the left edge of the ellipsis is to the left of our text run, then we are the run that will get truncated. if (ltr) { if (ellipsisX <= m_x) { // Too far. Just set full truncation, but return -1 and let the ellipsis just be placed at the edge of the box. m_truncation = cFullTruncation; foundBox = true; return -1; } if (ellipsisX < m_x + m_width) { if (direction() == RTL) return -1; // FIXME: Support LTR truncation when the last run is RTL someday. foundBox = true; int offset = offsetForPosition(ellipsisX, false); if (offset == 0) { // No characters should be rendered. Set ourselves to full truncation and place the ellipsis at the min of our start // and the ellipsis edge. m_truncation = cFullTruncation; return min(ellipsisX, m_x); } // Set the truncation index on the text run. The ellipsis needs to be placed just after the last visible character. m_truncation = offset; return m_x + static_cast<RenderText*>(m_object)->width(m_start, offset, textPos(), m_firstLine); } } else { // FIXME: Support RTL truncation someday, including both modes (when the leftmost run on the line is either RTL or LTR) } return -1; }
void MenuState::addMenuItem(MenuItem & item) { /* EntityFactory fact(getEngines()); Entity * guyEnt = fact.create< SingleVisualEntity>("bullet", item.MarkerPos); getEngines().entityEngine().addEntity(guyEnt, &getManagedEntityList()); */ // add text Vector2 textPos(item.MarkerPos.x() + 0.9f, item.MarkerPos.y() - 0.5f); TexturePtr textTex = getEngines().resourceEngine().loadImage("textChars"); auto textV = std14::make_unique<TextVisual>( getEngines().renderEngine().getScreenTransform(), textTex, textPos, item.Text); textV->setSizeScale(0.7f); item.TextVis = textV.get(); getEngines().renderEngine().addTextVisual(std::move(textV)); if (m_currentItem < 0) m_currentItem = 0; m_menuItems.push_back(item); }
void MapObjectLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { QColor color = MapObjectItem::objectColor(mObject); painter->setRenderHint(QPainter::Antialiasing); painter->setBrush(Qt::black); painter->setPen(Qt::NoPen); painter->drawRoundedRect(mBoundingRect.translated(1, 1), 4, 4); painter->setBrush(color); painter->drawRoundedRect(mBoundingRect, 4, 4); QPointF textPos(-(mBoundingRect.width() - labelMargin*4) / 2, -labelDistance); painter->drawRoundedRect(mBoundingRect, 4, 4); painter->setPen(Qt::black); painter->drawText(textPos + QPointF(1,1), mObject->name()); painter->setPen(Qt::white); painter->drawText(textPos, mObject->name()); }
/* ------------------------------------------------------------------------------ */ static int readEntry( FILE *is, const char *entry, char *buf, int bufSize, int strip ) { char lineBuf[256]; char *p, *cur; int len; bool quote = false; cur = buf; *cur = '\0'; len = -1; while( fgets( lineBuf, 256, is ) ) { remEOL(lineBuf); if( isTitleLine( lineBuf ) ) /* section is ended */ break; p = textPos( lineBuf, entry ); /* not equal this entry */ if( p == 0 ) continue; if( strip ) quote = stripQuotationChar( p ); if (quote == false) stripComment( p ); rtrim(p); len = (int)strlen(p); if( bufSize-1 < len ) len = bufSize-1; strncpy( cur, p, len ); cur[len] = 0; break; } return len; }
void Button::draw(NVGcontext *ctx) { Widget::draw(ctx); NVGcolor gradTop = mTheme->mButtonGradientTopUnfocused; NVGcolor gradBot = mTheme->mButtonGradientBotUnfocused; if (mPushed) { gradTop = mTheme->mButtonGradientTopPushed; gradBot = mTheme->mButtonGradientBotPushed; } else if (mMouseFocus && mEnabled) { gradTop = mTheme->mButtonGradientTopFocused; gradBot = mTheme->mButtonGradientBotFocused; } nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x() + 1, mPos.y() + 1.0f, mSize.x() - 2, mSize.y() - 2, mTheme->mButtonCornerRadius - 1); if(mBackgroundColor.w() != 0) { nvgFillColor(ctx, mBackgroundColor); nvgFill(ctx); if(mPushed) { gradTop.a = gradBot.a = 0.8f; } else { double v = 1-mBackgroundColor.w(); gradTop.a = gradBot.a = mEnabled ? v : 0.5f; gradTop.a = gradBot.a = (mMouseFocus && mEnabled) ? gradTop.a+0.2 : gradTop.a; } } NVGpaint bg = nvgLinearGradient(ctx, mPos.x(), mPos.y(), mPos.x(), mPos.y() + mSize.y(), gradTop, gradBot); nvgFillPaint(ctx, bg); nvgFill(ctx); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x() + 0.5f, mPos.y() + (mPushed ? 0.5f : 1.5f), mSize.x() - 1, mSize.y() - 1 - (mPushed ? 0.0f : 1.0f), mTheme->mButtonCornerRadius); nvgStrokeColor(ctx, mTheme->mBorderLight); nvgStroke(ctx); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x() + 0.5f, mPos.y() + 0.5f, mSize.x() - 1, mSize.y() - 2, mTheme->mButtonCornerRadius); nvgStrokeColor(ctx, mTheme->mBorderDark); nvgStroke(ctx); nvgFontSize(ctx, mFontSize == -1 ? mTheme->mButtonFontSize : mFontSize); nvgFontFace(ctx, "sans-bold"); float tw = nvgTextBounds(ctx, 0,0, mCaption.c_str(), nullptr, nullptr); Vector2f center = mPos.cast<float>() + mSize.cast<float>() * 0.5f; Vector2f textPos(center.x() - tw * 0.5f, center.y() - 1); NVGcolor textColor = mTextColor.w() == 0 ? mTheme->mTextColor : mTextColor; if (!mEnabled) textColor = mTheme->mDisabledTextColor; if (mIcon) { auto icon = utf8(mIcon); float iw, ih = mFontSize == -1 ? mTheme->mButtonFontSize : mFontSize; if (nvgIsFontIcon(mIcon)) { ih *= 1.5f; nvgFontSize(ctx, ih); nvgFontFace(ctx, "icons"); iw = nvgTextBounds(ctx, 0, 0, icon.data(), nullptr, nullptr); } else { int w, h; ih *= 0.9f; nvgImageSize(ctx, mIcon, &w, &h); iw = w * ih / h; } if (mCaption != "") iw += mSize.y() * 0.15f; nvgFillColor(ctx, textColor); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); Vector2f iconPos = center; iconPos.y() -= 1; if (mIconPosition == LeftCentered) { iconPos.x() -= (tw + iw) * 0.5f; textPos.x() += iw * 0.5f; } else if (mIconPosition == RightCentered) { textPos.x() -= iw * 0.5f; iconPos.x() += tw * 0.5f; } else if (mIconPosition == Left) { iconPos.x() = mPos.x() + 8; } else if (mIconPosition == Right) { iconPos.x() = mPos.x() + mSize.x() - iw - 8; } if (nvgIsFontIcon(mIcon)) { nvgText(ctx, iconPos.x(), iconPos.y()+1, icon.data(), nullptr); } else { NVGpaint imgPaint = nvgImagePattern(ctx, iconPos.x(), iconPos.y() - ih/2, iw, ih, 0, mIcon, mEnabled ? 0.5f : 0.25f); nvgFillPaint(ctx, imgPaint); nvgFill(ctx); } } nvgFontSize(ctx, mFontSize == -1 ? mTheme->mButtonFontSize : mFontSize); nvgFontFace(ctx, "sans-bold"); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); nvgFillColor(ctx, mTheme->mTextColorShadow); nvgText(ctx, textPos.x(), textPos.y(), mCaption.c_str(), nullptr); nvgFillColor(ctx, textColor); nvgText(ctx, textPos.x(), textPos.y()+1, mCaption.c_str(), nullptr); }
int InlineTextBox::positionForOffset(int offset) const { ASSERT(offset >= m_start); ASSERT(offset <= m_start + m_len); if (isLineBreak()) return m_x; RenderText* text = static_cast<RenderText*>(m_object); const Font& f = text->style(m_firstLine)->font(); int from = direction() == RTL ? offset - m_start : 0; int to = direction() == RTL ? m_len : offset - m_start; // FIXME: Do we need to add rightBearing here? return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride), IntPoint(m_x, 0), 0, from, to)).right(); }
IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos) { int sPos = max(startPos - m_start, 0); int ePos = min(endPos - m_start, (int)m_len); if (sPos >= ePos) return IntRect(); RenderText* textObj = textObject(); int selTop = selectionTop(); int selHeight = selectionHeight(); const Font& f = textObj->style(m_firstLine)->font(); IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(textObj->text()->characters() + m_start, m_len, textObj->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride), IntPoint(tx + m_x, ty + selTop), selHeight, sPos, ePos)); if (r.x() > tx + m_x + m_width) r.setWidth(0); else if (r.right() - 1 > tx + m_x + m_width) r.setWidth(tx + m_x + m_width - r.x()); return r; }
int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const { if (isLineBreak()) return 0; RenderText* text = static_cast<RenderText*>(m_object); RenderStyle *style = text->style(m_firstLine); const Font* f = &style->font(); return f->offsetForPosition(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()), _x - m_x, includePartialGlyphs); }
LayoutUnit InlineTextBox::placeEllipsisBox(bool flowIsLTR, LayoutUnit visibleLeftEdge, LayoutUnit visibleRightEdge, LayoutUnit ellipsisWidth, LayoutUnit &truncatedWidth, bool& foundBox) { if (foundBox) { setTruncation(cFullTruncation); return -1; } // For LTR this is the left edge of the box, for RTL, the right edge in parent coordinates. LayoutUnit ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWidth : visibleLeftEdge + ellipsisWidth; // Criteria for full truncation: // LTR: the left edge of the ellipsis is to the left of our text run. // RTL: the right edge of the ellipsis is to the right of our text run. bool ltrFullTruncation = flowIsLTR && ellipsisX <= logicalLeft(); bool rtlFullTruncation = !flowIsLTR && ellipsisX >= logicalLeft() + logicalWidth(); if (ltrFullTruncation || rtlFullTruncation) { // Too far. Just set full truncation, but return -1 and let the ellipsis just be placed at the edge of the box. setTruncation(cFullTruncation); foundBox = true; return -1; } bool ltrEllipsisWithinBox = flowIsLTR && (ellipsisX < logicalRight()); bool rtlEllipsisWithinBox = !flowIsLTR && (ellipsisX > logicalLeft()); if (ltrEllipsisWithinBox || rtlEllipsisWithinBox) { foundBox = true; // The inline box may have different directionality than it's parent. Since truncation // behavior depends both on both the parent and the inline block's directionality, we // must keep track of these separately. bool ltr = isLeftToRightDirection(); if (ltr != flowIsLTR) { // Width in pixels of the visible portion of the box, excluding the ellipsis. int visibleBoxWidth = visibleRightEdge - visibleLeftEdge - ellipsisWidth; ellipsisX = ltr ? logicalLeft() + visibleBoxWidth : logicalRight() - visibleBoxWidth; } int offset = offsetForPosition(ellipsisX, false); if (offset == 0) { // No characters should be laid out. Set ourselves to full truncation and place the ellipsis at the min of our start // and the ellipsis edge. setTruncation(cFullTruncation); truncatedWidth += ellipsisWidth; return std::min(ellipsisX, logicalLeft()); } // Set the truncation index on the text run. setTruncation(offset); // If we got here that means that we were only partially truncated and we need to return the pixel offset at which // to place the ellipsis. LayoutUnit widthOfVisibleText = lineLayoutItem().width(m_start, offset, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle()); // The ellipsis needs to be placed just after the last visible character. // Where "after" is defined by the flow directionality, not the inline // box directionality. // e.g. In the case of an LTR inline box truncated in an RTL flow then we can // have a situation such as |Hello| -> |...He| truncatedWidth += widthOfVisibleText + ellipsisWidth; if (flowIsLTR) return logicalLeft() + widthOfVisibleText; return logicalRight() - widthOfVisibleText - ellipsisWidth; } truncatedWidth += logicalWidth(); return -1; }
// This method is way too big, split it up a bit. LAgreementDlg::LAgreementDlg(Xvars &x_vars,int dpy_num,int argc,char** argv, Boolean lgViewportVal,Boolean smoothScrollVal, Boolean reduceDrawVal) { xvars = &x_vars; dpyNum = dpy_num; status = UNDECIDED; // User hasn't said yes or no yet. // Initialize this up at the top, so we get the right button states. currentPage = 0; // Create content model, the list of pages. parse(LAgreement::get_text()); // We should really just put this in Xvars. fontSize = xvars->fontSize[dpyNum]; // Compute sizes for the buttons. Size buttonSizes[BUTTONS_MAX]; int n; for (n = 0; n < BUTTONS_MAX; n++) { buttonSizes[n] = TextPanel::get_unit(xvars->font[dpyNum], Utils::strlen(buttonLabels[n])); } // Just used for the height, for two rows. Size optionTextUnit = TextPanel::get_unit(xvars->font[dpyNum],1,2); // Create window windowSize.width = fontSize.width * Line::get_text_columns() + 2 * TEXT_PADDING; windowSize.height = fontSize.height * Page::get_text_rows() + 2 * TEXT_PADDING // around the text in the main area + 1 // separator + (OPTIONS_MAX + 1) * TEXT_PADDING + OPTIONS_MAX * optionTextUnit.height + 1 // separator + 2 * BUTTON_VERT_PADDING + buttonSizes[0].height; window = xvars->create_toplevel_window(argc,argv,dpyNum,windowSize, "XEvil License Agreement",ExposureMask); // Compute location of the top separator line. separatorY_1 = fontSize.height * Page::get_text_rows() + 2 * TEXT_PADDING; // Compute max width of the option buttons. int optionsMaxWidth = 0; for (n = 0; n < OPTIONS_MAX; n++) { Size opSize = TogglePanel::get_unit(xvars->font[dpyNum], Utils::strlen(optionToggleLabels[n]),1); optionsMaxWidth = Utils::maximum(optionsMaxWidth,opSize.width); } // Now create the toggle buttons and corresponding text. Pos optionPos(OPTION_HORIZ_PADDING,separatorY_1 + 1 + TEXT_PADDING); for (n = 0; n < OPTIONS_MAX; n++) { // Create toggle button. Size optionToggleUnit = TogglePanel::get_unit(xvars->font[dpyNum], strlen(optionToggleLabels[n]),1); Pos togglePos(OPTION_HORIZ_PADDING, optionPos.y + optionTextUnit.height / 2 - optionToggleUnit.height / 2); optionToggles[n] = new TogglePanel(dpyNum,*xvars,window, togglePos,optionToggleUnit, // Don't care about callback. We will poll result when // dialog is popped down. NULL,NULL, optionToggleLabels[n]); assert(optionToggles[n]); // Create text for toggle button. Pos textPos(2 * OPTION_HORIZ_PADDING + optionsMaxWidth, optionPos.y); Size textUnit = TextPanel::get_unit(xvars->font[dpyNum],strlen(optionTextText[n]),2); optionText[n] = new TextPanel(dpyNum,*xvars,window, textPos,textUnit, NULL,NULL, optionTextText[n], // Don't want a border. TEXT_PANEL_EVENT_MASK,False); assert(optionText[n]); optionPos.y += optionTextUnit.height; } // Set initial values optionToggles[LARGE_VIEWPORT]->set_value(lgViewportVal); optionToggles[SMOOTH_SCROLL]->set_value(smoothScrollVal); optionToggles[DRAW_BACKGROUNDS]->set_value(!reduceDrawVal); // Location of the bottom separator line. separatorY_2 = separatorY_1 + 1 + (OPTIONS_MAX + 1) * TEXT_PADDING + OPTIONS_MAX * optionTextUnit.height; // Before creating the buttons. // Sets initial value of viewedBefore. check_viewed_before(); // Figure out where to place the buttons. Pos buttonPos[BUTTONS_MAX]; compute_button_pos(buttonPos,buttonSizes, windowSize.width, separatorY_2 + 1 + BUTTON_VERT_PADDING); // Create the buttons for (n = 0; n < BUTTONS_MAX; n++) { // Shareware labels. if (n == SHAREWARE_1 || n == SHAREWARE_2) { buttons[n] = new TextPanel(dpyNum,*xvars,window, buttonPos[n],buttonSizes[n], NULL,NULL,buttonLabels[n], TEXT_PANEL_EVENT_MASK, False); } // Normal buttons. else { buttons[n] = new ButtonPanel(dpyNum,*xvars,window, buttonPos[n],buttonSizes[n], button_callback,(void*)this, buttonLabels[n]); } assert(buttons[n]); buttons[n]->set_sensitive(get_button_sensitive(n)); } // Pop up the window. XMapWindow(xvars->dpy[dpyNum],window); }
PassOwnPtr<DragImage> DragImage::create(const KURL& url, const String& inLabel, const FontDescription& systemFont, float deviceScaleFactor) { const Font labelFont = deriveDragLabelFont(kDragLinkLabelFontSize, FontWeightBold, systemFont); const Font urlFont = deriveDragLabelFont(kDragLinkUrlFontSize, FontWeightNormal, systemFont); FontCachePurgePreventer fontCachePurgePreventer; bool drawURLString = true; bool clipURLString = false; bool clipLabelString = false; String urlString = url.string(); String label = inLabel.stripWhiteSpace(); if (label.isEmpty()) { drawURLString = false; label = urlString; } // First step is drawing the link drag image width. TextRun labelRun(label.impl()); TextRun urlRun(urlString.impl()); IntSize labelSize(labelFont.width(labelRun), labelFont.fontMetrics().ascent() + labelFont.fontMetrics().descent()); if (labelSize.width() > kMaxDragLabelStringWidth) { labelSize.setWidth(kMaxDragLabelStringWidth); clipLabelString = true; } IntSize urlStringSize; IntSize imageSize(labelSize.width() + kDragLabelBorderX * 2, labelSize.height() + kDragLabelBorderY * 2); if (drawURLString) { urlStringSize.setWidth(urlFont.width(urlRun)); urlStringSize.setHeight(urlFont.fontMetrics().ascent() + urlFont.fontMetrics().descent()); imageSize.setHeight(imageSize.height() + urlStringSize.height()); if (urlStringSize.width() > kMaxDragLabelStringWidth) { imageSize.setWidth(kMaxDragLabelWidth); clipURLString = true; } else imageSize.setWidth(std::max(labelSize.width(), urlStringSize.width()) + kDragLabelBorderX * 2); } // We now know how big the image needs to be, so we create and // fill the background IntSize scaledImageSize = imageSize; scaledImageSize.scale(deviceScaleFactor); OwnPtr<ImageBuffer> buffer(ImageBuffer::create(scaledImageSize)); if (!buffer) return nullptr; buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor)); const float DragLabelRadius = 5; const IntSize radii(DragLabelRadius, DragLabelRadius); IntRect rect(IntPoint(), imageSize); const Color backgroundColor(140, 140, 140); buffer->context()->fillRoundedRect(rect, radii, radii, radii, radii, backgroundColor); // Draw the text if (drawURLString) { if (clipURLString) urlString = StringTruncator::centerTruncate(urlString, imageSize.width() - (kDragLabelBorderX * 2.0f), urlFont, StringTruncator::EnableRoundingHacks); IntPoint textPos(kDragLabelBorderX, imageSize.height() - (kLabelBorderYOffset + urlFont.fontMetrics().descent())); TextRun textRun(urlString); buffer->context()->drawText(urlFont, TextRunPaintInfo(textRun), textPos); } if (clipLabelString) label = StringTruncator::rightTruncate(label, imageSize.width() - (kDragLabelBorderX * 2.0f), labelFont, StringTruncator::EnableRoundingHacks); bool hasStrongDirectionality; TextRun textRun = textRunWithDirectionality(label, hasStrongDirectionality); IntPoint textPos(kDragLabelBorderX, kDragLabelBorderY + labelFont.fontDescription().computedPixelSize()); if (hasStrongDirectionality && textRun.direction() == RTL) { float textWidth = urlFont.width(textRun); int availableWidth = imageSize.width() - kDragLabelBorderX * 2; textPos.setX(availableWidth - ceilf(textWidth)); } buffer->context()->drawBidiText(urlFont, TextRunPaintInfo(textRun), textPos); RefPtr<Image> image = buffer->copyImage(); return DragImage::create(image.get(), DoNotRespectImageOrientation, deviceScaleFactor); }
void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, int deco, ShadowData* shadow) { tx += m_x; ty += m_y; if (m_truncation == cFullTruncation) return; int width = (m_truncation == cNoTruncation) ? m_width : static_cast<RenderText*>(m_object)->width(m_start, m_truncation, textPos(), m_firstLine); // Get the text decoration colors. Color underline, overline, linethrough; object()->getTextDecorationColors(deco, underline, overline, linethrough, true); // Use a special function for underlines to get the positioning exactly right. bool isPrinting = textObject()->document()->printing(); context->setStrokeThickness(1.0f); // FIXME: We should improve this rule and not always just assume 1. bool linesAreOpaque = !isPrinting && (!(deco & UNDERLINE) || underline.alpha() == 255) && (!(deco & OVERLINE) || overline.alpha() == 255) && (!(deco & LINE_THROUGH) || linethrough.alpha() == 255); bool setClip = false; int extraOffset = 0; if (!linesAreOpaque && shadow && shadow->next) { context->save(); IntRect clipRect(tx, ty, width, m_baseline + 2); for (ShadowData* s = shadow; s; s = s->next) { IntRect shadowRect(tx, ty, width, m_baseline + 2); shadowRect.inflate(s->blur); shadowRect.move(s->x, s->y); clipRect.unite(shadowRect); extraOffset = max(extraOffset, max(0, s->y) + s->blur); } context->save(); context->clip(clipRect); extraOffset += m_baseline + 2; ty += extraOffset; setClip = true; } bool setShadow = false; do { if (shadow) { if (!shadow->next) { // The last set of lines paints normally inside the clip. ty -= extraOffset; extraOffset = 0; } context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color); setShadow = true; shadow = shadow->next; } if (deco & UNDERLINE) { context->setStrokeColor(underline); // Leave one pixel of white between the baseline and the underline. context->drawLineForText(IntPoint(tx, ty + m_baseline + 1), width, isPrinting); } if (deco & OVERLINE) { context->setStrokeColor(overline); context->drawLineForText(IntPoint(tx, ty), width, isPrinting); } if (deco & LINE_THROUGH) { context->setStrokeColor(linethrough); context->drawLineForText(IntPoint(tx, ty + 2 * m_baseline / 3), width, isPrinting); } } while (shadow); if (setClip) context->restore(); else if (setShadow) context->clearShadow(); }
void InlineTextBox::paintSelection(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font*) { // See if we have a selection to paint at all. int sPos, ePos; selectionStartEnd(sPos, ePos); if (sPos >= ePos) return; Color textColor = style->color(); Color c = object()->selectionBackgroundColor(); if (!c.isValid() || c.alpha() == 0) return; // If the text color ends up being the same as the selection background, invert the selection // background. This should basically never happen, since the selection has transparency. if (textColor == c) c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); context->save(); updateGraphicsContext(context, c, c, 0); // Don't draw text at all! int y = selectionTop(); int h = selectionHeight(); context->clip(IntRect(m_x + tx, y + ty, m_width, h)); context->drawHighlightForText(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()), IntPoint(m_x + tx, y + ty), h, c, sPos, ePos); context->restore(); }
void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty) { if (isLineBreak() || !object()->shouldPaintWithinRoot(paintInfo) || object()->style()->visibility() != VISIBLE || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline) return; ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines); int xPos = tx + m_x - parent()->maxHorizontalVisualOverflow(); int w = width() + 2 * parent()->maxHorizontalVisualOverflow(); if (xPos >= paintInfo.rect.right() || xPos + w <= paintInfo.rect.x()) return; bool isPrinting = textObject()->document()->printing(); // Determine whether or not we're selected. bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone; if (!haveSelection && paintInfo.phase == PaintPhaseSelection) // When only painting the selection, don't bother to paint if there is none. return; GraphicsContext* context = paintInfo.context; // Determine whether or not we have composition underlines to draw. bool containsComposition = object()->document()->frame()->editor()->compositionNode() == object()->node(); bool useCustomUnderlines = containsComposition && object()->document()->frame()->editor()->compositionUsesCustomUnderlines(); // Set our font. RenderStyle* styleToUse = object()->style(m_firstLine); int d = styleToUse->textDecorationsInEffect(); const Font* font = &styleToUse->font(); if (*font != context->font()) context->setFont(*font); // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection // and composition underlines. if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseTextClip && !isPrinting) { #if PLATFORM(MAC) // Custom highlighters go behind everything else. if (styleToUse->highlight() != nullAtom && !context->paintingDisabled()) paintCustomHighlight(tx, ty, styleToUse->highlight()); #endif if (containsComposition && !useCustomUnderlines) paintCompositionBackground(context, tx, ty, styleToUse, font, object()->document()->frame()->editor()->compositionStart(), object()->document()->frame()->editor()->compositionEnd()); paintDocumentMarkers(context, tx, ty, styleToUse, font, true); if (haveSelection && !useCustomUnderlines) paintSelection(context, tx, ty, styleToUse, font); } // 2. Now paint the foreground, including text and decorations like underline/overline (in quirks mode only). if (m_len <= 0) return; Color textFillColor; Color textStrokeColor; float textStrokeWidth = styleToUse->textStrokeWidth(); ShadowData* textShadow = paintInfo.forceBlackText ? 0 : styleToUse->textShadow(); if (paintInfo.forceBlackText) { textFillColor = Color::black; textStrokeColor = Color::black; } else { textFillColor = styleToUse->textFillColor(); if (!textFillColor.isValid()) textFillColor = styleToUse->color(); // Make the text fill color legible against a white background if (styleToUse->forceBackgroundsToWhite()) textFillColor = correctedTextColor(textFillColor, Color::white); textStrokeColor = styleToUse->textStrokeColor(); if (!textStrokeColor.isValid()) textStrokeColor = styleToUse->color(); // Make the text stroke color legible against a white background if (styleToUse->forceBackgroundsToWhite()) textStrokeColor = correctedTextColor(textStrokeColor, Color::white); } bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); bool paintSelectedTextSeparately = false; Color selectionFillColor = textFillColor; Color selectionStrokeColor = textStrokeColor; float selectionStrokeWidth = textStrokeWidth; ShadowData* selectionShadow = textShadow; if (haveSelection) { // Check foreground color first. Color foreground = paintInfo.forceBlackText ? Color::black : object()->selectionForegroundColor(); if (foreground.isValid() && foreground != selectionFillColor) { if (!paintSelectedTextOnly) paintSelectedTextSeparately = true; selectionFillColor = foreground; } if (RenderStyle* pseudoStyle = object()->getCachedPseudoStyle(RenderStyle::SELECTION)) { ShadowData* shadow = paintInfo.forceBlackText ? 0 : pseudoStyle->textShadow(); if (shadow != selectionShadow) { if (!paintSelectedTextOnly) paintSelectedTextSeparately = true; selectionShadow = shadow; } float strokeWidth = pseudoStyle->textStrokeWidth(); if (strokeWidth != selectionStrokeWidth) { if (!paintSelectedTextOnly) paintSelectedTextSeparately = true; selectionStrokeWidth = strokeWidth; } Color stroke = paintInfo.forceBlackText ? Color::black : pseudoStyle->textStrokeColor(); if (!stroke.isValid()) stroke = pseudoStyle->color(); if (stroke != selectionStrokeColor) { if (!paintSelectedTextOnly) paintSelectedTextSeparately = true; selectionStrokeColor = stroke; } } } IntPoint textOrigin(m_x + tx, m_y + ty + m_baseline); TextRun textRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || styleToUse->visuallyOrdered()); int sPos = 0; int ePos = 0; if (paintSelectedTextOnly || paintSelectedTextSeparately) selectionStartEnd(sPos, ePos); if (!paintSelectedTextOnly) { // For stroked painting, we have to change the text drawing mode. It's probably dangerous to leave that mutated as a side // effect, so only when we know we're stroking, do a save/restore. if (textStrokeWidth > 0) context->save(); updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth); if (!paintSelectedTextSeparately || ePos <= sPos) { // FIXME: Truncate right-to-left text correctly. paintTextWithShadows(context, textRun, 0, m_truncation == cNoTruncation ? m_len : m_truncation, textOrigin, m_x + tx, m_y + ty, width(), height(), textShadow, textStrokeWidth > 0); } else paintTextWithShadows(context, textRun, ePos, sPos, textOrigin, m_x + tx, m_y + ty, width(), height(), textShadow, textStrokeWidth > 0); if (textStrokeWidth > 0) context->restore(); } if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) { // paint only the text that is selected if (selectionStrokeWidth > 0) context->save(); updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth); paintTextWithShadows(context, textRun, sPos, ePos, textOrigin, m_x + tx, m_y + ty, width(), height(), selectionShadow, selectionStrokeWidth > 0); if (selectionStrokeWidth > 0) context->restore(); } // Paint decorations if (d != TDNONE && paintInfo.phase != PaintPhaseSelection && styleToUse->htmlHacks()) { context->setStrokeColor(styleToUse->color()); paintDecoration(context, tx, ty, d, textShadow); } if (paintInfo.phase == PaintPhaseForeground) { paintDocumentMarkers(context, tx, ty, styleToUse, font, false); if (useCustomUnderlines) { const Vector<CompositionUnderline>& underlines = object()->document()->frame()->editor()->customCompositionUnderlines(); size_t numUnderlines = underlines.size(); for (size_t index = 0; index < numUnderlines; ++index) { const CompositionUnderline& underline = underlines[index]; if (underline.endOffset <= start()) // underline is completely before this run. This might be an underline that sits // before the first run we draw, or underlines that were within runs we skipped // due to truncation. continue; if (underline.startOffset <= end()) { // underline intersects this run. Paint it. paintCompositionUnderline(context, tx, ty, underline); if (underline.endOffset > end() + 1) // underline also runs into the next run. Bail now, no more marker advancement. break; } else // underline is completely after this run, bail. A later run will paint it. break; } } } }
void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font* f, bool grammar) { // Never print spelling/grammar markers (5327887) if (textObject()->document()->printing()) return; if (m_truncation == cFullTruncation) return; int start = 0; // start of line to draw, relative to tx int width = m_width; // how much line to draw // Determine whether we need to measure text bool markerSpansWholeBox = true; if (m_start <= (int)marker.startOffset) markerSpansWholeBox = false; if ((end() + 1) != marker.endOffset) // end points at the last char, not past it markerSpansWholeBox = false; if (m_truncation != cNoTruncation) markerSpansWholeBox = false; if (!markerSpansWholeBox || grammar) { int startPosition = max<int>(marker.startOffset - m_start, 0); int endPosition = min<int>(marker.endOffset - m_start, m_len); if (m_truncation != cNoTruncation) endPosition = min<int>(endPosition, m_truncation); // Calculate start & width IntPoint startPoint(tx + m_x, ty + selectionTop()); TextRun run(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()); int h = selectionHeight(); IntRect markerRect = enclosingIntRect(f->selectionRectForText(run, startPoint, h, startPosition, endPosition)); start = markerRect.x() - startPoint.x(); width = markerRect.width(); // Store rendered rects for bad grammar markers, so we can hit-test against it elsewhere in order to // display a toolTip. We don't do this for misspelling markers. if (grammar) object()->document()->setRenderedRectForMarker(object()->node(), marker, markerRect); } // IMPORTANT: The misspelling underline is not considered when calculating the text bounds, so we have to // make sure to fit within those bounds. This means the top pixel(s) of the underline will overlap the // bottom pixel(s) of the glyphs in smaller font sizes. The alternatives are to increase the line spacing (bad!!) // or decrease the underline thickness. The overlap is actually the most useful, and matches what AppKit does. // So, we generally place the underline at the bottom of the text, but in larger fonts that's not so good so // we pin to two pixels under the baseline. int lineThickness = cMisspellingLineThickness; int descent = m_height - m_baseline; int underlineOffset; if (descent <= (2 + lineThickness)) { // place the underline at the very bottom of the text in small/medium fonts underlineOffset = m_height - lineThickness; } else { // in larger fonts, tho, place the underline up near the baseline to prevent big gap underlineOffset = m_baseline + 2; } pt->drawLineForMisspellingOrBadGrammar(IntPoint(tx + m_x + start, ty + m_y + underlineOffset), width, grammar); }
void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font* f) { // Use same y positioning and height as for selection, so that when the selection and this highlight are on // the same word there are no pieces sticking out. int y = selectionTop(); int h = selectionHeight(); int sPos = max(marker.startOffset - m_start, (unsigned)0); int ePos = min(marker.endOffset - m_start, (unsigned)m_len); TextRun run(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()); IntPoint startPoint = IntPoint(m_x + tx, y + ty); // Always compute and store the rect associated with this marker IntRect markerRect = enclosingIntRect(f->selectionRectForText(run, startPoint, h, sPos, ePos)); object()->document()->setRenderedRectForMarker(object()->node(), marker, markerRect); // Optionally highlight the text if (object()->document()->frame()->markedTextMatchesAreHighlighted()) { Color color = theme()->platformTextSearchHighlightColor(); pt->save(); updateGraphicsContext(pt, color, color, 0); // Don't draw text at all! pt->clip(IntRect(tx + m_x, ty + y, m_width, h)); pt->drawHighlightForText(run, startPoint, h, color, sPos, ePos); pt->restore(); } }
DragImageRef createDragImageForLink(URL& url, const String& inLabel, FontRenderingMode fontRenderingMode) { // This is more or less an exact match for the Mac OS X code. const Font* labelFont; const Font* urlFont; FontCachePurgePreventer fontCachePurgePreventer; if (fontRenderingMode == AlternateRenderingMode) { static const Font alternateRenderingModeLabelFont = dragLabelFont(DragLinkLabelFontsize, true, AlternateRenderingMode); static const Font alternateRenderingModeURLFont = dragLabelFont(DragLinkUrlFontSize, false, AlternateRenderingMode); labelFont = &alternateRenderingModeLabelFont; urlFont = &alternateRenderingModeURLFont; } else { static const Font normalRenderingModeLabelFont = dragLabelFont(DragLinkLabelFontsize, true, NormalRenderingMode); static const Font normalRenderingModeURLFont = dragLabelFont(DragLinkUrlFontSize, false, NormalRenderingMode); labelFont = &normalRenderingModeLabelFont; urlFont = &normalRenderingModeURLFont; } bool drawURLString = true; bool clipURLString = false; bool clipLabelString = false; String urlString = url.string(); String label = inLabel; if (label.isEmpty()) { drawURLString = false; label = urlString; } // First step in drawing the link drag image width. TextRun labelRun(label.impl()); TextRun urlRun(urlString.impl()); IntSize labelSize(labelFont->width(labelRun), labelFont->fontMetrics().ascent() + labelFont->fontMetrics().descent()); if (labelSize.width() > MaxDragLabelStringWidth) { labelSize.setWidth(MaxDragLabelStringWidth); clipLabelString = true; } IntSize urlStringSize; IntSize imageSize(labelSize.width() + DragLabelBorderX * 2, labelSize.height() + DragLabelBorderY * 2); if (drawURLString) { urlStringSize.setWidth(urlFont->width(urlRun)); urlStringSize.setHeight(urlFont->fontMetrics().ascent() + urlFont->fontMetrics().descent()); imageSize.setHeight(imageSize.height() + urlStringSize.height()); if (urlStringSize.width() > MaxDragLabelStringWidth) { imageSize.setWidth(MaxDragLabelWidth); clipURLString = true; } else imageSize.setWidth(std::max(labelSize.width(), urlStringSize.width()) + DragLabelBorderX * 2); } // We now know how big the image needs to be, so we create and // fill the background HWndDC dc(0); auto workingDC = adoptGDIObject(::CreateCompatibleDC(dc)); if (!workingDC) return 0; PlatformGraphicsContext* contextRef; auto image = allocImage(workingDC.get(), imageSize, &contextRef); if (!image) return 0; ::SelectObject(workingDC.get(), image.get()); GraphicsContext context(contextRef); // On Mac alpha is {0.7, 0.7, 0.7, 0.8}, however we can't control alpha // for drag images on win, so we use 1 static const Color backgroundColor(140, 140, 140); static const IntSize radii(DragLabelRadius, DragLabelRadius); IntRect rect(0, 0, imageSize.width(), imageSize.height()); context.fillRoundedRect(FloatRoundedRect(rect, radii, radii, radii, radii), backgroundColor, ColorSpaceDeviceRGB); // Draw the text static const Color topColor(0, 0, 0, 255); // original alpha = 0.75 static const Color bottomColor(255, 255, 255, 127); // original alpha = 0.5 if (drawURLString) { if (clipURLString) urlString = StringTruncator::rightTruncate(urlString, imageSize.width() - (DragLabelBorderX * 2.0f), *urlFont, StringTruncator::EnableRoundingHacks); IntPoint textPos(DragLabelBorderX, imageSize.height() - (LabelBorderYOffset + urlFont->fontMetrics().descent())); WebCoreDrawDoubledTextAtPoint(context, urlString, textPos, *urlFont, topColor, bottomColor); } if (clipLabelString) label = StringTruncator::rightTruncate(label, imageSize.width() - (DragLabelBorderX * 2.0f), *labelFont, StringTruncator::EnableRoundingHacks); IntPoint textPos(DragLabelBorderX, DragLabelBorderY + labelFont->pixelSize()); WebCoreDrawDoubledTextAtPoint(context, label, textPos, *labelFont, topColor, bottomColor); deallocContext(contextRef); return image.leak(); }
void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, int tx, int ty, const CompositionUnderline& underline) { tx += m_x; ty += m_y; if (m_truncation == cFullTruncation) return; int start = 0; // start of line to draw, relative to tx int width = m_width; // how much line to draw bool useWholeWidth = true; unsigned paintStart = m_start; unsigned paintEnd = end() + 1; // end points at the last char, not past it if (paintStart <= underline.startOffset) { paintStart = underline.startOffset; useWholeWidth = false; start = static_cast<RenderText*>(m_object)->width(m_start, paintStart - m_start, textPos(), m_firstLine); } if (paintEnd != underline.endOffset) { // end points at the last char, not past it paintEnd = min(paintEnd, (unsigned)underline.endOffset); useWholeWidth = false; } if (m_truncation != cNoTruncation) { paintEnd = min(paintEnd, (unsigned)m_start + m_truncation); useWholeWidth = false; } if (!useWholeWidth) { width = static_cast<RenderText*>(m_object)->width(paintStart, paintEnd - paintStart, textPos() + start, m_firstLine); } // Thick marked text underlines are 2px thick as long as there is room for the 2px line under the baseline. // All other marked text underlines are 1px thick. // If there's not enough space the underline will touch or overlap characters. int lineThickness = 1; if (underline.thick && m_height - m_baseline >= 2) lineThickness = 2; // We need to have some space between underlines of subsequent clauses, because some input methods do not use different underline styles for those. // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too. start += 1; width -= 2; ctx->setStrokeColor(underline.color); ctx->setStrokeThickness(lineThickness); ctx->drawLineForText(IntPoint(tx + start, ty + m_height - lineThickness), width, textObject()->document()->printing()); }
void InlineTextBox::paintCompositionBackground(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font*, int startPos, int endPos) { int offset = m_start; int sPos = max(startPos - offset, 0); int ePos = min(endPos - offset, (int)m_len); if (sPos >= ePos) return; context->save(); Color c = Color(225, 221, 85); updateGraphicsContext(context, c, c, 0); // Don't draw text at all! int y = selectionTop(); int h = selectionHeight(); context->drawHighlightForText(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()), IntPoint(m_x + tx, y + ty), h, c, sPos, ePos); context->restore(); }
void SidebarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QBrush backBrush; QColor foreColor; bool disabled = false; bool hover = false; if (!(option.state & QStyle::State_Enabled)) { backBrush = option.palette.brush(QPalette::Disabled, QPalette::Base); foreColor = option.palette.color(QPalette::Disabled, QPalette::Text); disabled = true; } else if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) { backBrush = option.palette.brush(QPalette::Highlight); foreColor = option.palette.color(QPalette::HighlightedText); } else if (option.state & QStyle::State_MouseOver) { backBrush = option.palette.color(QPalette::Highlight).light(115); foreColor = option.palette.color(QPalette::HighlightedText); hover = true; } else { /*if ( option.state & QStyle::State_Enabled )*/ backBrush = option.palette.brush(QPalette::Base); foreColor = option.palette.color(QPalette::Text); } QStyle *style = QApplication::style(); QStyleOptionViewItemV4 opt(option); // KStyle provides an "hover highlight" effect for free; // but we want that for non-KStyle-based styles too if (!style->inherits("KStyle") && hover) { Qt::BrushStyle bs = opt.backgroundBrush.style(); if (bs > Qt::NoBrush && bs < Qt::TexturePattern) opt.backgroundBrush = opt.backgroundBrush.color().light(115); else opt.backgroundBrush = backBrush; } painter->save(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, 0); painter->restore(); QIcon icon = index.data(Qt::DecorationRole).value< QIcon >(); if (!icon.isNull()) { QPoint iconpos( (option.rect.width() - option.decorationSize.width()) / 2, ITEM_MARGIN_TOP ); iconpos += option.rect.topLeft(); QIcon::Mode iconmode = disabled ? QIcon::Disabled : QIcon::Normal; painter->drawPixmap(iconpos, icon.pixmap(option.decorationSize, iconmode)); } if (m_showText) { QString text = index.data(Qt::DisplayRole).toString(); QRect fontBoundaries = QFontMetrics(option.font).boundingRect(text); fontBoundaries.setWidth(fontBoundaries.width() + ITEM_PADDING); QPoint textPos( ITEM_MARGIN_LEFT + (option.rect.width() - ITEM_MARGIN_LEFT - ITEM_MARGIN_RIGHT - fontBoundaries.width()) / 2, ITEM_MARGIN_TOP + option.decorationSize.height() + ITEM_PADDING ); fontBoundaries.translate(-fontBoundaries.topLeft()); fontBoundaries.translate(textPos); fontBoundaries.translate(option.rect.topLeft()); painter->setPen(foreColor); painter->drawText(fontBoundaries, Qt::AlignCenter, text); } }