Пример #1
0
bool SVGInlineTextBox::nodeAtPoint(HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit, LayoutUnit)
{
    // FIXME: integrate with InlineTextBox::nodeAtPoint better.
    ASSERT(!isLineBreak());

    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, result.hitTestRequest(), lineLayoutItem().style()->pointerEvents());
    bool isVisible = lineLayoutItem().style()->visibility() == VISIBLE;
    if (isVisible || !hitRules.requireVisible) {
        if (hitRules.canHitBoundingBox
                || (hitRules.canHitStroke && (lineLayoutItem().style()->svgStyle().hasStroke() || !hitRules.requireStroke))
                || (hitRules.canHitFill && (lineLayoutItem().style()->svgStyle().hasFill() || !hitRules.requireFill))) {
            LayoutPoint boxOrigin(x(), y());
            boxOrigin.moveBy(accumulatedOffset);
            LayoutRect rect(boxOrigin, size());
            if (locationInContainer.intersects(rect)) {
                LineLayoutSVGInlineText lineLayoutItem = LineLayoutSVGInlineText(this->lineLayoutItem());
                ASSERT(lineLayoutItem.scalingFactor());
                float baseline = lineLayoutItem.scaledFont().fontMetrics().floatAscent() / lineLayoutItem.scalingFactor();

                FloatPoint floatLocation = FloatPoint(locationInContainer.point());
                for (const SVGTextFragment& fragment : m_textFragments) {
                    FloatQuad fragmentQuad = fragment.boundingQuad(baseline);
                    if (fragmentQuad.containsPoint(floatLocation)) {
                        lineLayoutItem.updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
                        if (!result.addNodeToListBasedTestResult(lineLayoutItem.node(), locationInContainer, rect))
                            return true;
                    }
                }
            }
        }
    }
    return false;
}
Пример #2
0
static inline FloatRect calculateFragmentBoundaries(LineLayoutSVGInlineText textLineLayout, const SVGTextFragment& fragment)
{
    float scalingFactor = textLineLayout.scalingFactor();
    ASSERT(scalingFactor);
    float baseline = textLineLayout.scaledFont().fontMetrics().floatAscent() / scalingFactor;
    return fragment.boundingBox(baseline);
}
Пример #3
0
int SVGInlineTextBox::offsetForPositionInFragment(
    const SVGTextFragment& fragment,
    LayoutUnit position,
    bool includePartialGlyphs) const {
  LineLayoutSVGInlineText lineLayoutItem =
      LineLayoutSVGInlineText(this->getLineLayoutItem());

  float scalingFactor = lineLayoutItem.scalingFactor();
  ASSERT(scalingFactor);

  const ComputedStyle& style = lineLayoutItem.styleRef();

  TextRun textRun = constructTextRun(style, fragment);

  // Eventually handle lengthAdjust="spacingAndGlyphs".
  // FIXME: Handle vertical text.
  if (fragment.isTransformed()) {
    AffineTransform fragmentTransform = fragment.buildFragmentTransform();
    textRun.setHorizontalGlyphStretch(
        clampTo<float>(fragmentTransform.xScale()));
  }

  return fragment.characterOffset - start() +
         lineLayoutItem.scaledFont().offsetForPosition(
             textRun, position * scalingFactor, includePartialGlyphs);
}
Пример #4
0
FloatRect SVGInlineTextBox::selectionRectForTextFragment(
    const SVGTextFragment& fragment,
    int startPosition,
    int endPosition,
    const ComputedStyle& style) const {
  ASSERT(startPosition < endPosition);

  LineLayoutSVGInlineText lineLayoutItem =
      LineLayoutSVGInlineText(this->getLineLayoutItem());

  float scalingFactor = lineLayoutItem.scalingFactor();
  ASSERT(scalingFactor);

  const Font& scaledFont = lineLayoutItem.scaledFont();
  const SimpleFontData* fontData = scaledFont.primaryFont();
  DCHECK(fontData);
  if (!fontData)
    return FloatRect();

  const FontMetrics& scaledFontMetrics = fontData->getFontMetrics();
  FloatPoint textOrigin(fragment.x, fragment.y);
  if (scalingFactor != 1)
    textOrigin.scale(scalingFactor, scalingFactor);

  textOrigin.move(0, -scaledFontMetrics.floatAscent());

  FloatRect selectionRect = scaledFont.selectionRectForText(
      constructTextRun(style, fragment), textOrigin,
      fragment.height * scalingFactor, startPosition, endPosition);
  if (scalingFactor == 1)
    return selectionRect;

  selectionRect.scale(1 / scalingFactor);
  return selectionRect;
}
Пример #5
0
static inline FloatRect calculateFragmentBoundaries(LineLayoutSVGInlineText textLineLayout, const SVGTextFragment& fragment)
{
    float scalingFactor = textLineLayout.scalingFactor();
    ASSERT(scalingFactor);
    float baseline = textLineLayout.scaledFont().fontMetrics().floatAscent() / scalingFactor;

    AffineTransform fragmentTransform;
    FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height);
    fragment.buildFragmentTransform(fragmentTransform);
    return fragmentTransform.mapRect(fragmentRect);
}
SVGTextMetrics::SVGTextMetrics(LineLayoutSVGInlineText textLayoutItem, unsigned length, float width)
{
    ASSERT(textLayoutItem);

    float scalingFactor = textLayoutItem.scalingFactor();
    ASSERT(scalingFactor);

    m_width = width / scalingFactor;
    m_height = textLayoutItem.scaledFont().fontMetrics().floatHeight() / scalingFactor;

    m_length = length;
}
Пример #7
0
bool SVGInlineTextBox::nodeAtPoint(HitTestResult& result,
                                   const HitTestLocation& locationInContainer,
                                   const LayoutPoint& accumulatedOffset,
                                   LayoutUnit,
                                   LayoutUnit) {
  // FIXME: integrate with InlineTextBox::nodeAtPoint better.
  ASSERT(!isLineBreak());

  PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING,
                                 result.hitTestRequest(),
                                 getLineLayoutItem().style()->pointerEvents());
  bool isVisible =
      getLineLayoutItem().style()->visibility() == EVisibility::Visible;
  if (isVisible || !hitRules.requireVisible) {
    if (hitRules.canHitBoundingBox ||
        (hitRules.canHitStroke &&
         (getLineLayoutItem().style()->svgStyle().hasStroke() ||
          !hitRules.requireStroke)) ||
        (hitRules.canHitFill &&
         (getLineLayoutItem().style()->svgStyle().hasFill() ||
          !hitRules.requireFill))) {
      LayoutRect rect(topLeft(), LayoutSize(logicalWidth(), logicalHeight()));
      rect.moveBy(accumulatedOffset);
      if (locationInContainer.intersects(rect)) {
        LineLayoutSVGInlineText lineLayoutItem =
            LineLayoutSVGInlineText(this->getLineLayoutItem());
        const SimpleFontData* fontData =
            lineLayoutItem.scaledFont().primaryFont();
        DCHECK(fontData);
        if (!fontData)
          return false;

        DCHECK(lineLayoutItem.scalingFactor());
        float baseline = fontData->getFontMetrics().floatAscent() /
                         lineLayoutItem.scalingFactor();
        FloatPoint floatLocation = FloatPoint(locationInContainer.point());
        for (const SVGTextFragment& fragment : m_textFragments) {
          FloatQuad fragmentQuad = fragment.boundingQuad(baseline);
          if (fragmentQuad.containsPoint(floatLocation)) {
            lineLayoutItem.updateHitTestResult(
                result,
                locationInContainer.point() - toLayoutSize(accumulatedOffset));
            if (result.addNodeToListBasedTestResult(lineLayoutItem.node(),
                                                    locationInContainer,
                                                    rect) == StopHitTesting)
              return true;
          }
        }
      }
    }
  }
  return false;
}
Пример #8
0
LayoutRect SVGInlineTextBox::calculateBoundaries() const
{
    LineLayoutSVGInlineText lineLayoutItem = LineLayoutSVGInlineText(this->lineLayoutItem());
    float scalingFactor = lineLayoutItem.scalingFactor();
    ASSERT(scalingFactor);
    LayoutUnit baseline = lineLayoutItem.scaledFont().fontMetrics().floatAscent() / scalingFactor;

    LayoutRect textBoundingRect;
    for (const SVGTextFragment& fragment : m_textFragments)
        textBoundingRect.unite(LayoutRect(fragment.overflowBoundingBox(baseline)));

    return textBoundingRect;
}
SVGTextMetrics::SVGTextMetrics(LineLayoutSVGInlineText textLayoutItem, const TextRun& run)
{
    ASSERT(textLayoutItem);

    float scalingFactor = textLayoutItem.scalingFactor();
    ASSERT(scalingFactor);

    const Font& scaledFont = textLayoutItem.scaledFont();

    // Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
    m_width = scaledFont.width(run) / scalingFactor;
    m_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;

    ASSERT(run.length() >= 0);
    m_length = static_cast<unsigned>(run.length());
}
Пример #10
0
LayoutRect SVGInlineTextBox::calculateBoundaries() const {
  LineLayoutSVGInlineText lineLayoutItem =
      LineLayoutSVGInlineText(this->getLineLayoutItem());
  const SimpleFontData* fontData = lineLayoutItem.scaledFont().primaryFont();
  DCHECK(fontData);
  if (!fontData)
    return LayoutRect();

  float scalingFactor = lineLayoutItem.scalingFactor();
  ASSERT(scalingFactor);
  LayoutUnit baseline(fontData->getFontMetrics().floatAscent() / scalingFactor);

  LayoutRect textBoundingRect;
  for (const SVGTextFragment& fragment : m_textFragments)
    textBoundingRect.unite(LayoutRect(fragment.overflowBoundingBox(baseline)));

  return textBoundingRect;
}