Exemplo n.º 1
0
static CSSValueID determineTextDirection(DocumentFragment* vttRoot)
{
    ASSERT(vttRoot);

    // Apply the Unicode Bidirectional Algorithm's Paragraph Level steps to the
    // concatenation of the values of each WebVTT Text Object in nodes, in a
    // pre-order, depth-first traversal, excluding WebVTT Ruby Text Objects and
    // their descendants.
    TextDirection textDirection = LTR;
    Node* node = NodeTraversal::next(*vttRoot);
    while (node) {
        ASSERT(node->isDescendantOf(vttRoot));

        if (node->isTextNode()) {
            bool hasStrongDirectionality;
            textDirection = determineDirectionality(node->nodeValue(), hasStrongDirectionality);
            if (hasStrongDirectionality)
                break;
        } else if (node->isVTTElement()) {
            if (toVTTElement(node)->webVTTNodeType() == VTTNodeTypeRubyText) {
                node = NodeTraversal::nextSkippingChildren(*node);
                continue;
            }
        }

        node = NodeTraversal::next(*node);
    }
    return isLeftToRightDirection(textDirection) ? CSSValueLtr : CSSValueRtl;
}
Exemplo n.º 2
0
TextDirection HTMLElement::directionality(Node** strongDirectionalityTextNode) const
{
    if (isHTMLInputElement(*this)) {
        HTMLInputElement* inputElement = toHTMLInputElement(const_cast<HTMLElement*>(this));
        bool hasStrongDirectionality;
        TextDirection textDirection = determineDirectionality(inputElement->value(), &hasStrongDirectionality);
        if (strongDirectionalityTextNode)
            *strongDirectionalityTextNode = hasStrongDirectionality ? inputElement : 0;
        return textDirection;
    }

    Node* node = ComposedTreeTraversal::firstChild(*this);
    while (node) {
        // Skip bdi, script, style and text form controls.
        if (equalIgnoringCase(node->nodeName(), "bdi") || isHTMLScriptElement(*node) || isHTMLStyleElement(*node)
            || (node->isElementNode() && toElement(node)->isTextFormControl())) {
            node = ComposedTreeTraversal::nextSkippingChildren(*node, this);
            continue;
        }

        // Skip elements with valid dir attribute
        if (node->isElementNode()) {
            AtomicString dirAttributeValue = toElement(node)->fastGetAttribute(dirAttr);
            if (isValidDirAttribute(dirAttributeValue)) {
                node = ComposedTreeTraversal::nextSkippingChildren(*node, this);
                continue;
            }
        }

        if (node->isTextNode()) {
            bool hasStrongDirectionality;
            TextDirection textDirection = determineDirectionality(node->textContent(true), &hasStrongDirectionality);
            if (hasStrongDirectionality) {
                if (strongDirectionalityTextNode)
                    *strongDirectionalityTextNode = node;
                return textDirection;
            }
        }
        node = ComposedTreeTraversal::next(*node, this);
    }
    if (strongDirectionalityTextNode)
        *strongDirectionalityTextNode = 0;
    return LTR;
}
Exemplo n.º 3
0
TextRun constructTextRun(const Font& font,
                         const String& string,
                         const ComputedStyle& style,
                         TextRunFlags flags) {
  return constructTextRun(font, string, style,
                          string.isEmpty() || string.is8Bit()
                              ? LTR
                              : determineDirectionality(string),
                          flags);
}
TextMetrics* CanvasRenderingContext2D::measureText(const String& text) {
  TextMetrics* metrics = TextMetrics::create();

  // The style resolution required for fonts is not available in frame-less
  // documents.
  if (!canvas()->document().frame())
    return metrics;

  canvas()->document().updateStyleAndLayoutTreeForNode(canvas());
  const Font& font = accessFont();
  const SimpleFontData* fontData = font.primaryFont();
  DCHECK(fontData);
  if (!fontData)
    return metrics;

  TextDirection direction;
  if (state().getDirection() == CanvasRenderingContext2DState::DirectionInherit)
    direction = determineDirectionality(text);
  else
    direction = toTextDirection(state().getDirection(), canvas());
  TextRun textRun(text, 0, 0, TextRun::AllowTrailingExpansion |
                                  TextRun::ForbidLeadingExpansion,
                  direction, false);
  textRun.setNormalizeSpace(true);
  FloatRect textBounds = font.selectionRectForText(
      textRun, FloatPoint(), font.getFontDescription().computedSize(), 0, -1,
      true);

  // x direction
  metrics->setWidth(font.width(textRun));
  metrics->setActualBoundingBoxLeft(-textBounds.x());
  metrics->setActualBoundingBoxRight(textBounds.maxX());

  // y direction
  const FontMetrics& fontMetrics = fontData->getFontMetrics();
  const float ascent = fontMetrics.floatAscent();
  const float descent = fontMetrics.floatDescent();
  const float baselineY = getFontBaseline(fontMetrics);

  metrics->setFontBoundingBoxAscent(ascent - baselineY);
  metrics->setFontBoundingBoxDescent(descent + baselineY);
  metrics->setActualBoundingBoxAscent(-textBounds.y() - baselineY);
  metrics->setActualBoundingBoxDescent(textBounds.maxY() + baselineY);

  // Note : top/bottom and ascend/descend are currently the same, so there's no
  // difference between the EM box's top and bottom and the font's ascend and
  // descend
  metrics->setEmHeightAscent(0);
  metrics->setEmHeightDescent(0);

  metrics->setHangingBaseline(0.8f * ascent - baselineY);
  metrics->setAlphabeticBaseline(-baselineY);
  metrics->setIdeographicBaseline(-descent - baselineY);
  return metrics;
}
Exemplo n.º 5
0
static CSSValueID determineTextDirection(DocumentFragment* vttRoot)
{
    DEFINE_STATIC_LOCAL(const String, rtTag, ("rt"));
    ASSERT(vttRoot);

    // Apply the Unicode Bidirectional Algorithm's Paragraph Level steps to the
    // concatenation of the values of each WebVTT Text Object in nodes, in a
    // pre-order, depth-first traversal, excluding WebVTT Ruby Text Objects and
    // their descendants.
    TextDirection textDirection = LTR;
    for (Node* node = vttRoot->firstChild(); node; node = NodeTraversal::next(*node, vttRoot)) {
        if (!node->isTextNode() || node->localName() == rtTag)
            continue;

        bool hasStrongDirectionality;
        textDirection = determineDirectionality(node->nodeValue(), hasStrongDirectionality);
        if (hasStrongDirectionality)
            break;
    }
    return isLeftToRightDirection(textDirection) ? CSSValueLtr : CSSValueRtl;
}
Exemplo n.º 6
0
TextRun constructTextRun(RenderObject* context, const Font& font, const String& string, RenderStyle* style, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
{
    bool hasStrongDirectionality;
    return constructTextRun(context, font, string, style, determineDirectionality(string, hasStrongDirectionality), expansion, flags);
}