void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty) { GraphicsContext* context = paintInfo.context; RenderStyle* style = m_object->style(m_firstLine); if (style->font() != context->font()) context->setFont(style->font()); Color textColor = style->color(); if (textColor != context->fillColor()) context->setFillColor(textColor); bool setShadow = false; if (style->textShadow()) { context->setShadow(IntSize(style->textShadow()->x, style->textShadow()->y), style->textShadow()->blur, style->textShadow()->color); setShadow = true; } const String& str = m_str; TextStyle textStyle(0, 0, 0, false, style->visuallyOrdered()); context->drawText(TextRun(str.impl()), IntPoint(m_x + tx, m_y + ty + m_baseline), textStyle); if (setShadow) context->clearShadow(); if (m_markupBox) { // Paint the markup box tx += m_x + m_width - m_markupBox->xPos(); ty += m_y + m_baseline - (m_markupBox->yPos() + m_markupBox->baseline()); m_markupBox->paint(paintInfo, tx, ty); } }
void InlineTextBox::paint(RenderObject::PaintInfo& i, int tx, int ty) { if (object()->isBR() || object()->style()->visibility() != VISIBLE || m_truncation == cFullTruncation || i.phase == PaintActionOutline) return; if (i.phase == PaintActionSelection && object()->selectionState() == RenderObject::SelectionNone) // When only painting the selection, don't bother to paint if there is none. return; int xPos = tx + m_x; int w = width(); if ((xPos >= i.r.x() + i.r.width()) || (xPos + w <= i.r.x())) return; // Set our font. RenderStyle* styleToUse = object()->style(m_firstLine); int d = styleToUse->textDecorationsInEffect(); if (styleToUse->font() != i.p->font()) i.p->setFont(styleToUse->font()); const Font *font = &styleToUse->htmlFont(); bool haveSelection = selectionState() != RenderObject::SelectionNone; // Now calculate startPos and endPos, for painting selection. // We paint selection while endPos > 0 int ePos = 0, sPos = 0; if (haveSelection && !object()->canvas()->staticMode()) { selectionStartEnd(sPos, ePos); } if (styleToUse->color() != i.p->pen().color()) i.p->setPen(styleToUse->color()); if (m_len > 0 && i.phase != PaintActionSelection) { int endPoint = m_len; if (m_truncation != cNoTruncation) endPoint = m_truncation - m_start; if (styleToUse->textShadow()) paintShadow(i.p, font, tx, ty, styleToUse->textShadow()); if (!haveSelection || sPos != 0 || ePos != m_len) { font->drawText(i.p, m_x + tx, m_y + ty + m_baseline, renderText()->string()->s, renderText()->string()->l, m_start, endPoint, m_toAdd, m_reversed ? QPainter::RTL : QPainter::LTR); } } if (d != TDNONE && i.phase != PaintActionSelection && styleToUse->htmlHacks()) { i.p->setPen(styleToUse->color()); paintDecoration(i.p, font, tx, ty, d); } if (haveSelection && i.phase == PaintActionSelection) { //kdDebug(6040) << this << " paintSelection with startPos=" << sPos << " endPos=" << ePos << endl; if ( sPos < ePos ) paintSelection(font, renderText(), i.p, styleToUse, tx, ty, sPos, ePos, d); } }
static float textWidth(const RenderText& text, unsigned from, unsigned length, float xPosition, const RenderStyle& style) { if (style.font().isFixedPitch() || (!from && length == text.textLength())) return text.width(from, length, style.font(), xPosition, nullptr, nullptr); // FIXME: Add templated UChar/LChar paths. TextRun run = text.is8Bit() ? TextRun(text.characters8() + from, length) : TextRun(text.characters16() + from, length); run.setCharactersLength(text.textLength() - from); ASSERT(run.charactersLength() >= run.length()); run.setXPos(xPosition); return style.font().width(run); }
void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextDecoration decoration, const SVGTextFragment& fragment, RenderObject* decorationRenderer) { ASSERT(!m_paintingResource); ASSERT(m_paintingResourceMode != ApplyToDefaultMode); RenderStyle* decorationStyle = decorationRenderer->style(); ASSERT(decorationStyle); const Font& font = decorationStyle->font(); const FontMetrics& fontMetrics = font.fontMetrics(); // The initial y value refers to overline position. float thickness = thicknessForDecoration(decoration, font); if (fragment.width <= 0 && thickness <= 0) return; float y = fragment.y - fontMetrics.ascent() + positionOffsetForDecoration(decoration, fontMetrics, thickness); Path path; path.addRect(FloatRect(fragment.x, y, fragment.width, thickness)); context->save(); if (acquirePaintingResource(context, decorationRenderer, decorationStyle)) releasePaintingResource(context, &path); context->restore(); }
int RenderBR::lineHeight(bool firstLine, bool /*isRootLineBox*/) const { if (firstTextBox() && !firstTextBox()->isText()) return 0; if (firstLine) { RenderStyle* s = style(firstLine); Length lh = s->lineHeight(); if (lh.isNegative()) { if (s == style()) { if (m_lineHeight == -1) m_lineHeight = RenderObject::lineHeight(false); return m_lineHeight; } return s->font().lineSpacing(); } if (lh.isPercent()) return lh.calcMinValue(s->fontSize()); return lh.value(); } if (m_lineHeight == -1) m_lineHeight = RenderObject::lineHeight(false); return m_lineHeight; }
IntRect EllipsisBox::selectionRect(int tx, int ty) { RenderStyle* style = m_renderer->style(m_firstLine); const Font& f = style->font(); return enclosingIntRect(f.selectionRectForText(TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + root()->selectionTop()), root()->selectionHeight())); }
IntRect EllipsisBox::selectionRect() { RenderStyle* style = m_renderer->style(isFirstLineStyle()); const Font& font = style->font(); // FIXME: Why is this always LTR? Fix by passing correct text run flags below. return enclosingIntRect(font.selectionRectForText(RenderBlock::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(x(), y() + root()->selectionTopAdjustedForPrecedingBlock()), root()->selectionHeightAdjustedForPrecedingBlock())); }
void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) { GraphicsContext* context = paintInfo.context; RenderStyle* style = renderer().style(isFirstLineStyle()); const Font& font = style->font(); FloatPoint boxOrigin = locationIncludingFlipping(); boxOrigin.moveBy(FloatPoint(paintOffset)); if (!isHorizontal()) boxOrigin.move(0, -virtualLogicalHeight()); FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight())); GraphicsContextStateSaver stateSaver(*context); if (!isHorizontal()) context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clockwise)); FloatPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent()); bool isPrinting = renderer().document().printing(); bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone; if (haveSelection) paintSelection(context, boxOrigin, style, font); else if (paintInfo.phase == PaintPhaseSelection) return; TextPainter::Style textStyle = TextPainter::textPaintingStyle(renderer(), style, paintInfo.forceBlackText(), isPrinting); if (haveSelection) textStyle = TextPainter::selectionPaintingStyle(renderer(), true, paintInfo.forceBlackText(), isPrinting, textStyle); TextRun textRun = constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion); TextPainter textPainter(context, font, textRun, textOrigin, boxRect, isHorizontal()); textPainter.paint(0, m_str.length(), m_str.length(), textStyle); paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style); }
TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, unsigned position, unsigned length, TextDirection textDirection) { RenderStyle* style = text->style(); ASSERT(style); TextRun run(static_cast<const LChar*>(0) // characters, will be set below if non-zero. , 0 // length, will be set below if non-zero. , 0 // xPos, only relevant with allowTabs=true , 0 // padding, only relevant for justified text, not relevant for SVG , TextRun::AllowTrailingExpansion , textDirection , isOverride(style->unicodeBidi()) /* directionalOverride */); if (length) { if (text->is8Bit()) run.setText(text->characters8() + position, length); else run.setText(text->characters16() + position, length); } if (textRunNeedsRenderingContext(style->font())) run.setRenderingContext(SVGTextRunRenderingContext::create(text)); // We handle letter & word spacing ourselves. run.disableSpacing(); // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring. run.setCharactersLength(text->textLength() - position); ASSERT(run.charactersLength() >= run.length()); return run; }
IntRect SVGInlineTextBox::calculateBoundaries() const { FloatRect textRect; RenderText* textRenderer = this->textRenderer(); ASSERT(textRenderer); RenderStyle* style = textRenderer->style(); ASSERT(style); int baseline = baselinePosition(AlphabeticBaseline); int heightDifference = baseline - style->font().ascent(); unsigned textFragmentsSize = m_textFragments.size(); for (unsigned i = 0; i < textFragmentsSize; ++i) { const SVGTextFragment& fragment = m_textFragments.at(i); FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height + heightDifference); if (!fragment.transform.isIdentity()) fragmentRect = fragment.transform.mapRect(fragmentRect); textRect.unite(fragmentRect); } return enclosingIntRect(textRect); }
void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) { GraphicsContext* context = paintInfo.context; RenderStyle* style = m_renderer->style(isFirstLineStyle()); Color styleTextColor = style->visitedDependentColor(CSSPropertyWebkitTextFillColor); if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor, style->colorSpace()); Color textColor = styleTextColor; const Font& font = style->font(); if (selectionState() != RenderObject::SelectionNone) { paintSelection(context, paintOffset, style, font); // Select the correct color for painting the text. Color foreground = paintInfo.forceBlackText() ? Color::black : renderer()->selectionForegroundColor(); if (foreground.isValid() && foreground != styleTextColor) context->setFillColor(foreground, style->colorSpace()); } const ShadowData* shadow = style->textShadow(); bool hasShadow = shadow; if (hasShadow) { // FIXME: it would be better if we could get the shadows top-to-bottom from the style. Vector<const ShadowData*, 4> shadows; do { shadows.append(shadow); } while ((shadow = shadow->next())); DrawLooper drawLooper; drawLooper.addUnmodifiedContent(); for (int i = shadows.size() - 1; i >= 0; i--) { shadow = shadows[i]; int shadowX = isHorizontal() ? shadow->x() : shadow->y(); int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); FloatSize offset(shadowX, shadowY); drawLooper.addShadow(offset, shadow->blur(), shadow->color(), DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha); } context->setDrawLooper(drawLooper); } // FIXME: Why is this always LTR? Fix by passing correct text run flags below. FloatPoint boxOrigin(paintOffset); boxOrigin.move(x(), y()); FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), logicalHeight())); FloatPoint textOrigin(boxOrigin.x(), boxOrigin.y() + style->fontMetrics().ascent()); TextRun textRun = RenderBlock::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion); TextRunPaintInfo textRunPaintInfo(textRun); textRunPaintInfo.bounds = boxRect; context->drawText(font, textRunPaintInfo, textOrigin); // Restore the regular fill color. if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor, style->colorSpace()); if (hasShadow) context->clearDrawLooper(); paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style); }
bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty) { tx += m_x; ty += m_y; // Hit test the markup box. if (m_markupBox) { RenderStyle* style = m_renderer->style(m_firstLine); int mtx = tx + m_width - m_markupBox->x(); int mty = ty + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent()); if (m_markupBox->nodeAtPoint(request, result, x, y, mtx, mty)) { renderer()->updateHitTestResult(result, IntPoint(x - mtx, y - mty)); return true; } } IntRect boundsRect = IntRect(tx, ty, m_width, m_height); if (visibleToHitTesting() && boundsRect.intersects(result.rectFromPoint(x, y))) { renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, boundsRect)) return true; } return false; }
void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) { GraphicsContext* context = paintInfo.context; RenderStyle* style = renderer().style(isFirstLineStyle()); const Font& font = style->font(); FloatPoint boxOrigin = locationIncludingFlipping(); boxOrigin.moveBy(FloatPoint(paintOffset)); if (!isHorizontal()) boxOrigin.move(0, -virtualLogicalHeight()); FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight())); GraphicsContextStateSaver stateSaver(*context); if (!isHorizontal()) context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clockwise)); FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent()); Color styleTextColor = renderer().resolveColor(style, CSSPropertyWebkitTextFillColor); if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor); if (selectionState() != RenderObject::SelectionNone) { paintSelection(context, boxOrigin, style, font); // Select the correct color for painting the text. Color foreground = paintInfo.forceBlackText() ? Color::black : renderer().selectionForegroundColor(); if (foreground != styleTextColor) context->setFillColor(foreground); } // Text shadows are disabled when printing. http://crbug.com/258321 const ShadowList* shadowList = context->printing() ? 0 : style->textShadow(); bool hasShadow = shadowList; if (hasShadow) { OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create(); for (size_t i = shadowList->shadows().size(); i--; ) { const ShadowData& shadow = shadowList->shadows()[i]; float shadowX = isHorizontal() ? shadow.x() : shadow.y(); float shadowY = isHorizontal() ? shadow.y() : -shadow.x(); FloatSize offset(shadowX, shadowY); drawLooperBuilder->addShadow(offset, shadow.blur(), shadow.color(), DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha); } drawLooperBuilder->addUnmodifiedContent(); context->setDrawLooper(drawLooperBuilder.release()); } TextRun textRun = RenderBlockFlow::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion); TextRunPaintInfo textRunPaintInfo(textRun); textRunPaintInfo.bounds = boxRect; context->drawText(font, textRunPaintInfo, textOrigin); // Restore the regular fill color. if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor); if (hasShadow) context->clearDrawLooper(); paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style); }
PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const { HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node()); HTMLElement* element = select->listItems()[listIndex]; RenderStyle* style = element->renderStyle() ? element->renderStyle() : element->computedStyle(); return style ? PopupMenuStyle(style->color(), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->textIndent(), style->direction()) : menuStyle(); }
void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r) { if (p->paintingDisabled() || !m_qtMovie || m_hasUnsupportedTracks) return; bool usingTempBitmap = false; OwnPtr<GraphicsContext::WindowsBitmap> bitmap; HDC hdc = p->getWindowsContext(r); if (!hdc) { // The graphics context doesn't have an associated HDC so create a temporary // bitmap where QTMovieWin can draw the frame and we can copy it. usingTempBitmap = true; bitmap.set(p->createWindowsBitmap(r.size())); hdc = bitmap->hdc(); // FIXME: is this necessary?? XFORM xform; xform.eM11 = 1.0f; xform.eM12 = 0.0f; xform.eM21 = 0.0f; xform.eM22 = 1.0f; xform.eDx = -r.x(); xform.eDy = -r.y(); SetWorldTransform(hdc, &xform); } m_qtMovie->paint(hdc, r.x(), r.y()); if (usingTempBitmap) p->drawWindowsBitmap(bitmap.get(), r.topLeft()); else p->releaseWindowsContext(hdc, r); #if DRAW_FRAME_RATE if (m_frameCountWhilePlaying > 10) { Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL; Document* document = frame ? frame->document() : NULL; RenderObject* renderer = document ? document->renderer() : NULL; RenderStyle* styleToUse = renderer ? renderer->style() : NULL; if (styleToUse) { double frameRate = (m_frameCountWhilePlaying - 1) / (0.001 * ( m_startedPlaying ? (GetTickCount() - m_timeStartedPlaying) : (m_timeStoppedPlaying - m_timeStartedPlaying) )); String text = String::format("%1.2f", frameRate); TextRun textRun(text.characters(), text.length()); const Color color(255, 0, 0); p->save(); p->translate(r.x(), r.y() + r.height()); p->setFont(styleToUse->font()); p->setStrokeColor(color); p->setStrokeStyle(SolidStroke); p->setStrokeThickness(1.0f); p->setFillColor(color); p->drawText(textRun, IntPoint(2, -3)); p->restore(); } } #endif }
void InlineFlowBox::paintDecorations(RenderObject::PaintInfo& pI, int _tx, int _ty, bool paintedChildren) { // Now paint our text decorations. We only do this if we aren't in quirks mode (i.e., in // almost-strict mode or strict mode). if (object()->style()->htmlHacks() || object()->style()->visibility() != VISIBLE) return; _tx += m_x; _ty += m_y; RenderStyle* styleToUse = object()->style(m_firstLine); int deco = parent() ? styleToUse->textDecoration() : styleToUse->textDecorationsInEffect(); if (deco != TDNONE && ((!paintedChildren && ((deco & UNDERLINE) || (deco & OVERLINE))) || (paintedChildren && (deco & LINE_THROUGH))) && shouldDrawDecoration(object())) { // We must have child boxes and have decorations defined. _tx += borderLeft() + paddingLeft(); int w = m_width - (borderLeft() + paddingLeft() + borderRight() + paddingRight()); if ( !w ) return; const QFontMetrics &fm = object()->fontMetrics( m_firstLine ); // thick lines on small fonts look ugly int thickness = fm.height() > 20 ? fm.lineWidth() : 1; QColor underline, overline, linethrough; underline = overline = linethrough = styleToUse->color(); if (!parent()) object()->getTextDecorationColors(deco, underline, overline, linethrough); if (styleToUse->font() != pI.p->font()) pI.p->setFont(styleToUse->font()); if (deco & UNDERLINE && !paintedChildren) { int underlineOffset = ( fm.height() + m_baseline ) / 2; if (underlineOffset <= m_baseline) underlineOffset = m_baseline+1; pI.p->fillRect(_tx, _ty + underlineOffset, w, thickness, underline ); } if (deco & OVERLINE && !paintedChildren) { pI.p->fillRect(_tx, _ty, w, thickness, overline ); } if (deco & LINE_THROUGH && paintedChildren) { pI.p->fillRect(_tx, _ty + 2*m_baseline/3, w, thickness, linethrough ); } } }
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); }
Style(const RenderStyle& style) : font(style.font()) , textAlign(style.textAlign()) , collapseWhitespace(style.collapseWhiteSpace()) , preserveNewline(style.preserveNewline()) , wrapLines(style.autoWrap()) , breakWordOnOverflow(style.overflowWrap() == BreakOverflowWrap && (wrapLines || preserveNewline)) , spaceWidth(font.width(TextRun(&space, 1))) , tabWidth(collapseWhitespace ? 0 : style.tabSize()) { }
float SVGLength::convertValueFromEXSToUserUnits(float value, const SVGElement* context, ExceptionCode& ec) const { if (!context || !context->renderer() || !context->renderer()->style()) { ec = NOT_SUPPORTED_ERR; return 0; } RenderStyle* style = context->renderer()->style(); // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg // if this causes problems in real world cases maybe it would be best to remove this return value * ceilf(style->font().xHeight()); }
TQString RenderStyle::createDiff( const RenderStyle &parent ) const { TQString res; if ( color().isValid() && parent.color() != color() ) res += " [color=" + color().name() + "]"; if ( backgroundColor().isValid() && parent.backgroundColor() != backgroundColor() ) res += " [bgcolor=" + backgroundColor().name() + "]"; if ( parent.font() != font() ) res += " [font=" + describeFont( font() ) + "]"; return res; }
void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty) { GraphicsContext* context = paintInfo.context; RenderStyle* style = m_renderer->style(m_firstLine); Color textColor = style->color(); if (textColor != context->fillColor()) context->setFillColor(textColor, style->colorSpace()); bool setShadow = false; if (style->textShadow()) { context->setShadow(IntSize(style->textShadow()->x, style->textShadow()->y), style->textShadow()->blur, style->textShadow()->color, style->colorSpace()); setShadow = true; } if (selectionState() != RenderObject::SelectionNone) { paintSelection(context, tx, ty, style, style->font()); // Select the correct color for painting the text. Color foreground = paintInfo.forceBlackText ? Color::black : renderer()->selectionForegroundColor(); if (foreground.isValid() && foreground != textColor) context->setFillColor(foreground, style->colorSpace()); } const String& str = m_str; context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->font().ascent())); // Restore the regular fill color. if (textColor != context->fillColor()) context->setFillColor(textColor, style->colorSpace()); if (setShadow) context->clearShadow(); if (m_markupBox) { // Paint the markup box tx += m_x + m_width - m_markupBox->x(); ty += m_y + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent()); m_markupBox->paint(paintInfo, tx, ty); } }
VisiblePosition RenderSVGInlineText::positionForPoint(const IntPoint& point) { if (!firstTextBox() || !textLength()) return createVisiblePosition(0, DOWNSTREAM); RenderStyle* style = this->style(); ASSERT(style); int baseline = style->font().ascent(); RenderBlock* containingBlock = this->containingBlock(); ASSERT(containingBlock); // Map local point to absolute point, as the character origins stored in the text fragments use absolute coordinates. FloatPoint absolutePoint(point); absolutePoint.move(containingBlock->x(), containingBlock->y()); float closestDistance = std::numeric_limits<float>::max(); float closestDistancePosition = 0; const SVGTextFragment* closestDistanceFragment = 0; SVGInlineTextBox* closestDistanceBox = 0; for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { ASSERT(box->isSVGInlineTextBox()); SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(box); Vector<SVGTextFragment>& fragments = textBox->textFragments(); unsigned textFragmentsSize = fragments.size(); for (unsigned i = 0; i < textFragmentsSize; ++i) { const SVGTextFragment& fragment = fragments.at(i); FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height); if (!fragment.transform.isIdentity()) fragmentRect = fragment.transform.mapRect(fragmentRect); float distance = powf(fragmentRect.x() - absolutePoint.x(), 2) + powf(fragmentRect.y() + fragmentRect.height() / 2 - absolutePoint.y(), 2); if (distance < closestDistance) { closestDistance = distance; closestDistanceBox = textBox; closestDistanceFragment = &fragment; closestDistancePosition = fragmentRect.x(); } } } if (!closestDistanceFragment) return createVisiblePosition(0, DOWNSTREAM); int offset = closestDistanceBox->offsetForPositionInFragment(*closestDistanceFragment, absolutePoint.x() - closestDistancePosition, true); return createVisiblePosition(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM); }
float SVGLength::value() const { SVGLengthType type = extractType(m_unit); if (type == LengthTypeUnknown) return 0.0f; switch (type) { case LengthTypeNumber: return m_valueInSpecifiedUnits; case LengthTypePercentage: return SVGLength::PercentageOfViewport(m_valueInSpecifiedUnits / 100.0f, m_context, extractMode(m_unit)); case LengthTypeEMS: case LengthTypeEXS: { RenderStyle* style = 0; if (m_context && m_context->renderer()) style = m_context->renderer()->style(); if (style) { float useSize = style->fontSize(); ASSERT(useSize > 0); if (type == LengthTypeEMS) return m_valueInSpecifiedUnits * useSize; else { float xHeight = style->font().xHeight(); // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg // if this causes problems in real world cases maybe it would be best to remove this return m_valueInSpecifiedUnits * ceilf(xHeight); } } return 0.0f; } case LengthTypePX: return m_valueInSpecifiedUnits; case LengthTypeCM: return m_valueInSpecifiedUnits / 2.54f * cssPixelsPerInch; case LengthTypeMM: return m_valueInSpecifiedUnits / 25.4f * cssPixelsPerInch; case LengthTypeIN: return m_valueInSpecifiedUnits * cssPixelsPerInch; case LengthTypePT: return m_valueInSpecifiedUnits / 72.0f * cssPixelsPerInch; case LengthTypePC: return m_valueInSpecifiedUnits / 6.0f * cssPixelsPerInch; default: break; } ASSERT_NOT_REACHED(); return 0.0f; }
void RenderFileUploadControl::computePreferredLogicalWidths() { ASSERT(preferredLogicalWidthsDirty()); m_minPreferredLogicalWidth = 0; m_maxPreferredLogicalWidth = 0; RenderStyle* style = this->style(); ASSERT(style); const Font& font = style->font(); if (style->width().isFixed() && style->width().value() > 0) m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style->width().value()); else { // Figure out how big the filename space needs to be for a given number of characters // (using "0" as the nominal character). const UChar character = '0'; const String characterAsString = String(&character, 1); float minDefaultLabelWidth = defaultWidthNumChars * font.width(constructTextRun(this, font, characterAsString, style, TextRun::AllowTrailingExpansion)); const String label = theme()->fileListDefaultLabel(node()->toInputElement()->multiple()); float defaultLabelWidth = font.width(constructTextRun(this, font, label, style, TextRun::AllowTrailingExpansion)); if (HTMLInputElement* button = uploadButton()) if (RenderObject* buttonRenderer = button->renderer()) defaultLabelWidth += buttonRenderer->maxPreferredLogicalWidth() + afterButtonSpacing; m_maxPreferredLogicalWidth = static_cast<int>(ceilf(max(minDefaultLabelWidth, defaultLabelWidth))); } if (style->minWidth().isFixed() && style->minWidth().value() > 0) { m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style->minWidth().value())); m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style->minWidth().value())); } else if (style->width().isPercent() || (style->width().isAuto() && style->height().isPercent())) m_minPreferredLogicalWidth = 0; else m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth; if (style->maxWidth().isFixed()) { m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style->maxWidth().value())); m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style->maxWidth().value())); } int toAdd = borderAndPaddingWidth(); m_minPreferredLogicalWidth += toAdd; m_maxPreferredLogicalWidth += toAdd; setPreferredLogicalWidthsDirty(false); }
void RenderThemeSafari::setFontFromControlSize(StyleResolver& styleResolver, RenderStyle& style, NSControlSize controlSize) const { FontDescription fontDescription; fontDescription.setIsAbsoluteSize(true); fontDescription.setGenericFamily(FontDescription::SerifFamily); float fontSize = systemFontSizeForControlSize(controlSize); fontDescription.setOneFamily("Lucida Grande"); fontDescription.setComputedSize(fontSize); fontDescription.setSpecifiedSize(fontSize); // Reset line height style.setLineHeight(RenderStyle::initialLineHeight()); if (style.setFontDescription(fontDescription)) style.font().update(styleResolver.fontSelector()); }
int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragment, float position, bool includePartialGlyphs) const { RenderText* textRenderer = this->textRenderer(); ASSERT(textRenderer); RenderStyle* style = textRenderer->style(); ASSERT(style); TextRun textRun(constructTextRun(style, fragment)); // Eventually handle lengthAdjust="spacingAndGlyphs". // FIXME: Handle vertical text. if (!fragment.transform.isIdentity()) textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragment.transform.xScale())); return fragment.positionListOffset - start() + style->font().offsetForPosition(textRun, position, includePartialGlyphs); }
void SVGLength::updateValue(bool notify) { switch(m_unitType) { case SVG_LENGTHTYPE_PX: m_value = m_valueInSpecifiedUnits; break; case SVG_LENGTHTYPE_CM: m_value = (m_valueInSpecifiedUnits / 2.54) * dpi(); break; case SVG_LENGTHTYPE_MM: m_value = (m_valueInSpecifiedUnits / 25.4) * dpi(); break; case SVG_LENGTHTYPE_IN: m_value = m_valueInSpecifiedUnits * dpi(); break; case SVG_LENGTHTYPE_PT: m_value = (m_valueInSpecifiedUnits / 72.0) * dpi(); break; case SVG_LENGTHTYPE_PC: m_value = (m_valueInSpecifiedUnits / 6.0) * dpi(); break; case SVG_LENGTHTYPE_EMS: case SVG_LENGTHTYPE_EXS: if (m_context && m_context->renderer()) { RenderStyle *style = m_context->renderer()->style(); float useSize = style->fontSize(); ASSERT(useSize > 0); if (m_unitType == SVG_LENGTHTYPE_EMS) m_value = m_valueInSpecifiedUnits * useSize; else { float xHeight = style->font().xHeight(); // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg // if this causes problems in real world cases maybe it would be best to remove this m_value = m_valueInSpecifiedUnits * ceil(xHeight); } m_requiresLayout = false; } else { m_requiresLayout = true; } break; } if (notify && m_context) m_context->notifyAttributeChange(); }
void RenderSVGInlineText::computeNewScaledFontForStyle(const RenderObject& renderer, const RenderStyle& style, float& scalingFactor, Font& scaledFont) { // Alter font-size to the right on-screen value to avoid scaling the glyphs themselves, except when GeometricPrecision is specified scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(renderer); if (scalingFactor == 1 || !scalingFactor || style.fontDescription().textRenderingMode() == GeometricPrecision) { scalingFactor = 1; scaledFont = style.font(); return; } FontDescription fontDescription(style.fontDescription()); // FIXME: We need to better handle the case when we compute very small fonts below (below 1pt). fontDescription.setComputedSize(Style::computedFontSizeFromSpecifiedSizeForSVGInlineText(fontDescription.computedSize(), fontDescription.isAbsoluteSize(), scalingFactor, renderer.document())); scaledFont = Font(fontDescription, 0, 0); scaledFont.update(renderer.document().ensureStyleResolver().fontSelector()); }
void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) { GraphicsContext* context = paintInfo.context; RenderStyle* style = renderer().style(isFirstLineStyle()); const Font& font = style->font(); FloatPoint boxOrigin = locationIncludingFlipping(); boxOrigin.moveBy(FloatPoint(paintOffset)); FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight())); GraphicsContextStateSaver stateSaver(*context); FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent()); Color styleTextColor = renderer().resolveColor(style, CSSPropertyWebkitTextFillColor); if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor); if (selectionState() != RenderObject::SelectionNone) { paintSelection(context, boxOrigin, style, font); // Select the correct color for painting the text. Color foreground = paintInfo.forceBlackText() ? Color::black : renderer().selectionForegroundColor(); if (foreground != styleTextColor) context->setFillColor(foreground); } const ShadowList* shadowList = style->textShadow(); bool hasShadow = shadowList; if (hasShadow) context->setDrawLooper(shadowList->createDrawLooper(DrawLooperBuilder::ShadowIgnoresAlpha)); TextRun textRun = constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion); TextRunPaintInfo textRunPaintInfo(textRun); textRunPaintInfo.bounds = boxRect; context->drawText(font, textRunPaintInfo, textOrigin); // Restore the regular fill color. if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor); if (hasShadow) context->clearDrawLooper(); paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style); }
void RenderFileUploadControl::computePreferredLogicalWidths() { ASSERT(preferredLogicalWidthsDirty()); m_minPreferredLogicalWidth = 0; m_maxPreferredLogicalWidth = 0; RenderStyle* style = this->style(); ASSERT(style); const Font& font = style->font(); if (style->width().isFixed() && style->width().value() > 0) m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style->width().value()); else { // Figure out how big the filename space needs to be for a given number of characters // (using "0" as the nominal character). const UChar ch = '0'; const String str = String(&ch, 1); float charWidth = font.width(constructTextRun(this, font, str, style, TextRun::AllowTrailingExpansion)); m_maxPreferredLogicalWidth = (int)ceilf(charWidth * defaultWidthNumChars); } if (style->minWidth().isFixed() && style->minWidth().value() > 0) { m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style->minWidth().value())); m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style->minWidth().value())); } else if (style->width().isPercent() || (style->width().isAuto() && style->height().isPercent())) m_minPreferredLogicalWidth = 0; else m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth; if (style->maxWidth().isFixed()) { m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style->maxWidth().value())); m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style->maxWidth().value())); } int toAdd = borderAndPaddingWidth(); m_minPreferredLogicalWidth += toAdd; m_maxPreferredLogicalWidth += toAdd; setPreferredLogicalWidthsDirty(false); }