Ejemplo n.º 1
0
void BackgroundImageGeometry::setRepeatY(const FillLayer& fillLayer,
                                         LayoutUnit unsnappedTileHeight,
                                         LayoutUnit snappedAvailableHeight,
                                         LayoutUnit unsnappedAvailableHeight,
                                         LayoutUnit extraOffset) {
  // We would like to identify the phase as a fraction of the image size in the
  // absence of snapping, then re-apply it to the snapped values. This is to
  // handle large positions.
  if (unsnappedTileHeight) {
    LayoutUnit computedYPosition = roundedMinimumValueForLength(
        fillLayer.yPosition(), unsnappedAvailableHeight);
    if (fillLayer.backgroundYOrigin() == BottomEdge) {
      float numberOfTilesInPosition =
          (snappedAvailableHeight - computedYPosition + extraOffset).toFloat() /
          unsnappedTileHeight.toFloat();
      float fractionalPositionWithinTile =
          numberOfTilesInPosition - truncf(numberOfTilesInPosition);
      setPhaseY(LayoutUnit(
          roundf(fractionalPositionWithinTile * tileSize().height())));
    } else {
      float numberOfTilesInPosition =
          (computedYPosition + extraOffset).toFloat() /
          unsnappedTileHeight.toFloat();
      float fractionalPositionWithinTile =
          1.0f - (numberOfTilesInPosition - truncf(numberOfTilesInPosition));
      setPhaseY(LayoutUnit(
          roundf(fractionalPositionWithinTile * tileSize().height())));
    }
  } else {
    setPhaseY(LayoutUnit());
  }
  setSpaceSize(LayoutSize(spaceSize().width(), LayoutUnit()));
}
Ejemplo n.º 2
0
LineSegment PolygonShape::getExcludedInterval(LayoutUnit logicalTop, LayoutUnit logicalHeight) const
{
    float y1 = logicalTop.toFloat();
    float y2 = logicalTop.toFloat() + logicalHeight.toFloat();

    if (m_polygon.isEmpty() || !overlapsYRange(m_polygon.boundingBox(), y1 - shapeMargin(), y2 + shapeMargin()))
        return LineSegment();

    Vector<const FloatPolygonEdge*> overlappingEdges;
    if (!m_polygon.overlappingEdges(y1 - shapeMargin(), y2 + shapeMargin(), overlappingEdges))
        return LineSegment();

    FloatShapeInterval excludedInterval;
    for (unsigned i = 0; i < overlappingEdges.size(); i++) {
        const FloatPolygonEdge& edge = *(overlappingEdges[i]);
        if (edge.maxY() == edge.minY())
            continue;
        if (!shapeMargin()) {
            excludedInterval.unite(OffsetPolygonEdge(edge, FloatSize()).clippedEdgeXRange(y1, y2));
        } else {
            excludedInterval.unite(OffsetPolygonEdge(edge, outwardEdgeNormal(edge) * shapeMargin()).clippedEdgeXRange(y1, y2));
            excludedInterval.unite(OffsetPolygonEdge(edge, inwardEdgeNormal(edge) * shapeMargin()).clippedEdgeXRange(y1, y2));
            excludedInterval.unite(clippedCircleXRange(edge.vertex1(), shapeMargin(), y1, y2));
        }
    }

    if (excludedInterval.isEmpty())
        return LineSegment();

    return LineSegment(excludedInterval.x1(), excludedInterval.x2());
}
Ejemplo n.º 3
0
Vector<double> SnapCoordinator::snapOffsets(const ContainerNode& element,
                                            ScrollbarOrientation orientation) {
  const ComputedStyle* style = element.computedStyle();
  const LayoutBox* snapContainer = element.layoutBox();
  ASSERT(style);
  ASSERT(snapContainer);

  Vector<double> result;

  if (style->getScrollSnapType() == ScrollSnapTypeNone)
    return result;

  const ScrollSnapPoints& snapPoints = (orientation == HorizontalScrollbar)
                                           ? style->scrollSnapPointsX()
                                           : style->scrollSnapPointsY();

  LayoutUnit clientSize = (orientation == HorizontalScrollbar)
                              ? snapContainer->clientWidth()
                              : snapContainer->clientHeight();
  LayoutUnit scrollSize = (orientation == HorizontalScrollbar)
                              ? snapContainer->scrollWidth()
                              : snapContainer->scrollHeight();

  if (snapPoints.hasRepeat) {
    LayoutUnit repeat = valueForLength(snapPoints.repeatOffset, clientSize);

    // calc() values may be negative or zero in which case we clamp them to 1px.
    // See: https://lists.w3.org/Archives/Public/www-style/2015Jul/0075.html
    repeat = std::max<LayoutUnit>(repeat, LayoutUnit(1));
    for (LayoutUnit offset = repeat; offset <= (scrollSize - clientSize);
         offset += repeat) {
      result.append(offset.toFloat());
    }
  }

  // Compute element-based snap points by mapping the snap coordinates from
  // snap areas to snap container.
  bool didAddSnapAreaOffset = false;
  if (SnapAreaSet* snapAreas = snapContainer->snapAreas()) {
    for (auto& snapArea : *snapAreas) {
      Vector<FloatPoint> snapCoordinates =
          localToContainerSnapCoordinates(*snapContainer, *snapArea);
      for (const FloatPoint& snapCoordinate : snapCoordinates) {
        float snapOffset = (orientation == HorizontalScrollbar)
                               ? snapCoordinate.x()
                               : snapCoordinate.y();
        if (snapOffset > scrollSize - clientSize)
          continue;
        result.append(snapOffset);
        didAddSnapAreaOffset = true;
      }
    }
  }

  if (didAddSnapAreaOffset)
    std::sort(result.begin(), result.end());

  return result;
}
void FileUploadControlPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    if (m_layoutFileUploadControl.style()->visibility() != VISIBLE)
        return;

    // Push a clip.
    Optional<ClipRecorder> clipRecorder;
    if (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseDescendantBlockBackgroundsOnly) {
        IntRect clipRect = enclosingIntRect(LayoutRect(
            LayoutPoint(paintOffset.x() + m_layoutFileUploadControl.borderLeft(), paintOffset.y() + m_layoutFileUploadControl.borderTop()),
            m_layoutFileUploadControl.size() + LayoutSize(0, -m_layoutFileUploadControl.borderWidth() + buttonShadowHeight)));
        if (clipRect.isEmpty())
            return;
        clipRecorder.emplace(paintInfo.context, m_layoutFileUploadControl, DisplayItem::ClipFileUploadControlRect, clipRect);
    }

    if (paintInfo.phase == PaintPhaseForeground && !LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_layoutFileUploadControl, paintInfo.phase)) {
        const String& displayedFilename = m_layoutFileUploadControl.fileTextValue();
        const Font& font = m_layoutFileUploadControl.style()->font();
        TextRun textRun = constructTextRun(font, displayedFilename, m_layoutFileUploadControl.styleRef(), RespectDirection | RespectDirectionOverride);
        textRun.setExpansionBehavior(TextRun::AllowTrailingExpansion);

        // Determine where the filename should be placed
        LayoutUnit contentLeft = paintOffset.x() + m_layoutFileUploadControl.borderLeft() + m_layoutFileUploadControl.paddingLeft();
        Node* button = m_layoutFileUploadControl.uploadButton();
        if (!button)
            return;

        int buttonWidth = (button && button->layoutBox()) ? button->layoutBox()->pixelSnappedWidth() : 0;
        LayoutUnit buttonAndSpacingWidth(buttonWidth + LayoutFileUploadControl::afterButtonSpacing);
        float textWidth = font.width(textRun);
        LayoutUnit textX;
        if (m_layoutFileUploadControl.style()->isLeftToRightDirection())
            textX = contentLeft + buttonAndSpacingWidth;
        else
            textX = LayoutUnit(contentLeft + m_layoutFileUploadControl.contentWidth() - buttonAndSpacingWidth - textWidth);

        LayoutUnit textY;
        // We want to match the button's baseline
        // FIXME: Make this work with transforms.
        if (LayoutButton* buttonLayoutObject = toLayoutButton(button->layoutObject()))
            textY = paintOffset.y() + m_layoutFileUploadControl.borderTop() + m_layoutFileUploadControl.paddingTop() + buttonLayoutObject->baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine);
        else
            textY = LayoutUnit(m_layoutFileUploadControl.baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine));
        TextRunPaintInfo textRunPaintInfo(textRun);
        // FIXME: Shouldn't these offsets be rounded? crbug.com/350474
        textRunPaintInfo.bounds = FloatRect(textX.toFloat(), textY.toFloat() - m_layoutFileUploadControl.style()->getFontMetrics().ascent(),
            textWidth, m_layoutFileUploadControl.style()->getFontMetrics().height());

        // Draw the filename.
        LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutFileUploadControl, paintInfo.phase, textRunPaintInfo.bounds);
        paintInfo.context.setFillColor(m_layoutFileUploadControl.resolveColor(CSSPropertyColor));
        paintInfo.context.drawBidiText(font, textRunPaintInfo, FloatPoint(roundToInt(textX), roundToInt(textY)));
    }

    // Paint the children.
    m_layoutFileUploadControl.LayoutBlockFlow::paintObject(paintInfo, paintOffset);
}
Ejemplo n.º 5
0
void FileUploadControlPainter::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    if (m_renderFileUploadControl.style()->visibility() != VISIBLE)
        return;

    // Push a clip.
    GraphicsContextStateSaver stateSaver(*paintInfo.context, false);
    if (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseChildBlockBackgrounds) {
        IntRect clipRect = enclosingIntRect(LayoutRect(paintOffset.x() + m_renderFileUploadControl.borderLeft(), paintOffset.y() + m_renderFileUploadControl.borderTop(),
            m_renderFileUploadControl.width() - m_renderFileUploadControl.borderLeft() - m_renderFileUploadControl.borderRight(),
            m_renderFileUploadControl.height() - m_renderFileUploadControl.borderBottom() - m_renderFileUploadControl.borderTop() + buttonShadowHeight));
        if (clipRect.isEmpty())
            return;
        stateSaver.save();
        paintInfo.context->clip(clipRect);
    }

    if (paintInfo.phase == PaintPhaseForeground) {
        const String& displayedFilename = m_renderFileUploadControl.fileTextValue();
        const Font& font = m_renderFileUploadControl.style()->font();
        TextRun textRun = constructTextRun(&m_renderFileUploadControl, font, displayedFilename, m_renderFileUploadControl.style(), TextRun::AllowTrailingExpansion, RespectDirection | RespectDirectionOverride);

        // Determine where the filename should be placed
        LayoutUnit contentLeft = paintOffset.x() + m_renderFileUploadControl.borderLeft() + m_renderFileUploadControl.paddingLeft();
        Node* button = m_renderFileUploadControl.uploadButton();
        if (!button)
            return;

        int buttonWidth = (button && button->renderBox()) ? button->renderBox()->pixelSnappedWidth() : 0;
        LayoutUnit buttonAndSpacingWidth = buttonWidth + RenderFileUploadControl::afterButtonSpacing;
        float textWidth = font.width(textRun);
        LayoutUnit textX;
        if (m_renderFileUploadControl.style()->isLeftToRightDirection())
            textX = contentLeft + buttonAndSpacingWidth;
        else
            textX = contentLeft + m_renderFileUploadControl.contentWidth() - buttonAndSpacingWidth - textWidth;

        LayoutUnit textY = 0;
        // We want to match the button's baseline
        // FIXME: Make this work with transforms.
        if (RenderButton* buttonRenderer = toRenderButton(button->renderer()))
            textY = paintOffset.y() + m_renderFileUploadControl.borderTop() + m_renderFileUploadControl.paddingTop() + buttonRenderer->baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine);
        else
            textY = m_renderFileUploadControl.baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine);
        TextRunPaintInfo textRunPaintInfo(textRun);
        // FIXME: Shouldn't these offsets be rounded? crbug.com/350474
        textRunPaintInfo.bounds = FloatRect(textX.toFloat(), textY.toFloat() - m_renderFileUploadControl.style()->fontMetrics().ascent(),
            textWidth, m_renderFileUploadControl.style()->fontMetrics().height());

        paintInfo.context->setFillColor(m_renderFileUploadControl.resolveColor(CSSPropertyColor));

        // Draw the filename
        paintInfo.context->drawBidiText(font, textRunPaintInfo, IntPoint(roundToInt(textX), roundToInt(textY)));
    }

    // Paint the children.
    m_renderFileUploadControl.RenderBlockFlow::paintObject(paintInfo, paintOffset);
}
Ejemplo n.º 6
0
void KeyboardApplet::updateTooltip()
{
    LayoutUnit layoutUnit = X11Helper::getCurrentLayout();
    if( layoutUnit.isEmpty() )
        return;

    const QIcon icon(getFlag(layoutUnit.layout));
    Plasma::ToolTipContent data(name(), flags.getLongText(layoutUnit, rules), icon);
    Plasma::ToolTipManager::self()->setContent(this, data);
}
Ejemplo n.º 7
0
Path HTMLAreaElement::getRegion(const LayoutSize& size) const
{
    if (m_coords.isEmpty() && m_shape != Default)
        return Path();

    LayoutUnit width = size.width();
    LayoutUnit height = size.height();

    // If element omits the shape attribute, select shape based on number of coordinates.
    Shape shape = m_shape;
    if (shape == Unknown) {
        if (m_coords.size() == 3)
            shape = Circle;
        else if (m_coords.size() == 4)
            shape = Rect;
        else if (m_coords.size() >= 6)
            shape = Poly;
    }

    Path path;
    switch (shape) {
        case Poly:
            if (m_coords.size() >= 6) {
                int numPoints = m_coords.size() / 2;
                path.moveTo(FloatPoint(minimumValueForLength(m_coords[0], width).toFloat(), minimumValueForLength(m_coords[1], height).toFloat()));
                for (int i = 1; i < numPoints; ++i)
                    path.addLineTo(FloatPoint(minimumValueForLength(m_coords[i * 2], width).toFloat(), minimumValueForLength(m_coords[i * 2 + 1], height).toFloat()));
                path.closeSubpath();
            }
            break;
        case Circle:
            if (m_coords.size() >= 3) {
                Length radius = m_coords[2];
                float r = std::min(minimumValueForLength(radius, width).toFloat(), minimumValueForLength(radius, height).toFloat());
                path.addEllipse(FloatRect(minimumValueForLength(m_coords[0], width).toFloat() - r, minimumValueForLength(m_coords[1], height).toFloat() - r, 2 * r, 2 * r));
            }
            break;
        case Rect:
            if (m_coords.size() >= 4) {
                float x0 = minimumValueForLength(m_coords[0], width).toFloat();
                float y0 = minimumValueForLength(m_coords[1], height).toFloat();
                float x1 = minimumValueForLength(m_coords[2], width).toFloat();
                float y1 = minimumValueForLength(m_coords[3], height).toFloat();
                path.addRect(FloatRect(x0, y0, x1 - x0, y1 - y0));
            }
            break;
        case Default:
            path.addRect(FloatRect(0, 0, width.toFloat(), height.toFloat()));
            break;
        case Unknown:
            break;
    }

    return path;
}
Ejemplo n.º 8
0
int LayoutTextControl::textBlockLogicalWidth() const {
    Element* innerEditor = innerEditorElement();
    ASSERT(innerEditor);

    LayoutUnit unitWidth = logicalWidth() - borderAndPaddingLogicalWidth();
    if (innerEditor->layoutObject())
        unitWidth -= innerEditor->layoutBox()->paddingStart() +
                     innerEditor->layoutBox()->paddingEnd();

    return unitWidth.toInt();
}
Ejemplo n.º 9
0
TEST(LayoutUnitTest, UnaryMinus) {
  EXPECT_EQ(LayoutUnit(), -LayoutUnit());
  EXPECT_EQ(LayoutUnit(999), -LayoutUnit(-999));
  EXPECT_EQ(LayoutUnit(-999), -LayoutUnit(999));

  LayoutUnit negativeMax;
  negativeMax.setRawValue(LayoutUnit::min().rawValue() + 1);
  EXPECT_EQ(negativeMax, -LayoutUnit::max());
  EXPECT_EQ(LayoutUnit::max(), -negativeMax);

  // -LayoutUnit::min() is saturated to LayoutUnit::max()
  EXPECT_EQ(LayoutUnit::max(), -LayoutUnit::min());
}
Ejemplo n.º 10
0
const Shape& ShapeOutsideInfo::computedShape() const {
  if (Shape* shape = m_shape.get())
    return *shape;

  AutoReset<bool> isInComputingShape(&m_isComputingShape, true);

  const ComputedStyle& style = *m_layoutBox.style();
  ASSERT(m_layoutBox.containingBlock());
  const ComputedStyle& containingBlockStyle =
      *m_layoutBox.containingBlock()->style();

  WritingMode writingMode = containingBlockStyle.getWritingMode();
  // Make sure contentWidth is not negative. This can happen when containing
  // block has a vertical scrollbar and its content is smaller than the
  // scrollbar width.
  LayoutUnit maximumValue =
      m_layoutBox.containingBlock()
          ? std::max(LayoutUnit(),
                     m_layoutBox.containingBlock()->contentWidth())
          : LayoutUnit();
  float margin = floatValueForLength(m_layoutBox.style()->shapeMargin(),
                                     maximumValue.toFloat());

  float shapeImageThreshold = style.shapeImageThreshold();
  ASSERT(style.shapeOutside());
  const ShapeValue& shapeValue = *style.shapeOutside();

  switch (shapeValue.type()) {
    case ShapeValue::Shape:
      ASSERT(shapeValue.shape());
      m_shape = Shape::createShape(
          shapeValue.shape(), m_referenceBoxLogicalSize, writingMode, margin);
      break;
    case ShapeValue::Image:
      ASSERT(shapeValue.isImageValid());
      m_shape = createShapeForImage(shapeValue.image(), shapeImageThreshold,
                                    writingMode, margin);
      break;
    case ShapeValue::Box: {
      const FloatRoundedRect& shapeRect = style.getRoundedBorderFor(
          LayoutRect(LayoutPoint(), m_referenceBoxLogicalSize),
          m_layoutBox.view());
      m_shape = Shape::createLayoutBoxShape(shapeRect, writingMode, margin);
      break;
    }
  }

  ASSERT(m_shape);
  return *m_shape;
}
Ejemplo n.º 11
0
unsigned RenderMultiColumnSet::columnCount() const
{
    // We must always return a value of 1 or greater. Column count = 0 is a meaningless situation,
    // and will confuse and cause problems in other parts of the code.
    if (!computedColumnHeight())
        return 1;

    // Our portion rect determines our column count. We have as many columns as needed to fit all the content.
    LayoutUnit logicalHeightInColumns = flowThread()->isHorizontalWritingMode() ? flowThreadPortionRect().height() : flowThreadPortionRect().width();
    if (!logicalHeightInColumns)
        return 1;

    unsigned count = ceil(logicalHeightInColumns.toFloat() / computedColumnHeight().toFloat());
    ASSERT(count >= 1);
    return count;
}
LayoutUnit LayoutMultiColumnSet::nextLogicalTopForUnbreakableContent(LayoutUnit flowThreadOffset, LayoutUnit contentLogicalHeight) const
{
    ASSERT(flowThreadOffset.mightBeSaturated() || pageLogicalTopForOffset(flowThreadOffset) == flowThreadOffset);
    FragmentationContext* enclosingFragmentationContext = multiColumnFlowThread()->enclosingFragmentationContext();
    if (!enclosingFragmentationContext) {
        // If there's no enclosing fragmentation context, there'll ever be only one row, and all
        // columns there will have the same height.
        return flowThreadOffset;
    }

    // Assert the problematic situation. If we have no problem with the column height, why are we
    // even here?
    ASSERT(pageLogicalHeightForOffset(flowThreadOffset) < contentLogicalHeight);

    // There's a likelihood for subsequent rows to be taller than the first one.
    // TODO(mstensho): if we're doubly nested (e.g. multicol in multicol in multicol), we need to
    // look beyond the first row here.
    const MultiColumnFragmentainerGroup& firstRow = firstFragmentainerGroup();
    LayoutUnit firstRowLogicalBottomInFlowThread = firstRow.logicalTopInFlowThread() + fragmentainerGroupCapacity(firstRow);
    if (flowThreadOffset >= firstRowLogicalBottomInFlowThread)
        return flowThreadOffset; // We're not in the first row. Give up.
    LayoutUnit newLogicalHeight = enclosingFragmentationContext->fragmentainerLogicalHeightAt(firstRow.blockOffsetInEnclosingFragmentationContext() + firstRow.logicalHeight());
    if (contentLogicalHeight > newLogicalHeight) {
        // The next outer column or page doesn't have enough space either. Give up and stay where
        // we are.
        return flowThreadOffset;
    }
    return firstRowLogicalBottomInFlowThread;
}
Ejemplo n.º 13
0
LineSegment RectangleShape::getExcludedInterval(LayoutUnit logicalTop, LayoutUnit logicalHeight) const
{
    const FloatRect& bounds = shapeMarginBounds();
    if (bounds.isEmpty())
        return LineSegment();

    float y1 = logicalTop.toFloat();
    float y2 = (logicalTop + logicalHeight).toFloat();

    if (y2 < bounds.y() || y1 >= bounds.maxY())
        return LineSegment();

    float x1 = bounds.x();
    float x2 = bounds.maxX();

    float marginRadiusX = rx() + shapeMargin();
    float marginRadiusY = ry() + shapeMargin();

    if (marginRadiusY > 0) {
        if (y2 < bounds.y() + marginRadiusY) {
            float yi = y2 - bounds.y() - marginRadiusY;
            float xi = ellipseXIntercept(yi, marginRadiusX, marginRadiusY);
            x1 = bounds.x() + marginRadiusX - xi;
            x2 = bounds.maxX() - marginRadiusX + xi;
        } else if (y1 > bounds.maxY() - marginRadiusY) {
            float yi =  y1 - (bounds.maxY() - marginRadiusY);
            float xi = ellipseXIntercept(yi, marginRadiusX, marginRadiusY);
            x1 = bounds.x() + marginRadiusX - xi;
            x2 = bounds.maxX() - marginRadiusX + xi;
        }
    }

    return LineSegment(x1, x2);
}
static LayoutUnit computeMargin(const Length& length, LayoutUnit referenceLength)
{
    if (length.type() == Percent)
        return LayoutUnit(static_cast<int>(referenceLength.toFloat() * length.percent() / 100.0));
    ASSERT(length.type() == Fixed);
    return LayoutUnit(length.intValue());
}
Ejemplo n.º 15
0
bool RasterShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit& result) const
{
    const RasterShapeIntervals& intervals = paddingIntervals();
    if (intervals.isEmpty())
        return false;

    return intervals.firstIncludedIntervalY(minLogicalIntervalTop.floor(), flooredIntSize(minLogicalIntervalSize), result);
}
unsigned MultiColumnFragmentainerGroup::actualColumnCount() const
{
    // We must always return a value of 1 or greater. Column count = 0 is a meaningless situation,
    // and will confuse and cause problems in other parts of the code.
    if (!m_columnHeight)
        return 1;

    // Our flow thread portion determines our column count. We have as many columns as needed to fit
    // all the content.
    LayoutUnit flowThreadPortionHeight = logicalHeightInFlowThread();
    if (!flowThreadPortionHeight)
        return 1;

    unsigned count = ceil(flowThreadPortionHeight.toFloat() / m_columnHeight.toFloat());
    ASSERT(count >= 1);
    return count;
}
Ejemplo n.º 17
0
void LineWidth::updateLineDimension(LayoutUnit newLineTop, LayoutUnit newLineWidth, const float& newLineLeft, const float& newLineRight)
{
    if (newLineWidth <= m_availableWidth)
        return;

    m_block.setLogicalHeight(newLineTop);
    m_availableWidth = newLineWidth.toFloat();
    m_left = newLineLeft;
    m_right = newLineRight;
}
Ejemplo n.º 18
0
void LayoutConfig::latinChanged()
{
    QListViewItem *selLayout = widget->listLayoutsDst->selectedItem();
    if(!selLayout)
    {
        widget->chkLatin->setChecked(false);
        widget->chkLatin->setEnabled(false);
        return;
    }

    QString include;
    if(widget->chkLatin->isChecked())
        include = "us";
    else
        include = "";
    selLayout->setText(LAYOUT_COLUMN_INCLUDE, include);

    LayoutUnit layoutUnitKey = getLayoutUnitKey(selLayout);
    kdDebug() << "layout " << layoutUnitKey.toPair() << ", inc: " << include << endl;
}
Ejemplo n.º 19
0
void KeyboardApplet::paintInterface(QPainter *p, const QStyleOptionGraphicsItem */*option*/, const QRect &contentsRect)
{
    LayoutUnit layoutUnit = X11Helper::getCurrentLayout();
    if( layoutUnit.isEmpty() )
        return;

    const QIcon icon(getFlag(layoutUnit.layout));
    if( ! icon.isNull() ) {
        p->save();
        p->setRenderHint(QPainter::SmoothPixmapTransform);
        p->setRenderHint(QPainter::Antialiasing);
        QPixmap pixmap = icon.pixmap(contentsRect.size());
        p->drawPixmap(contentsRect, pixmap);
        p->restore();
    }
    if( icon.isNull() || keyboardConfig->isLabelShown() ) {
        QRect finalRect(m_pixmap.rect());
        finalRect.moveCenter(contentsRect.center());
        p->drawPixmap(finalRect, m_pixmap);
    }
}
Ejemplo n.º 20
0
void EllipsisBox::paintSelection(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font)
{
    Color textColor = renderer().resolveColor(style, CSSPropertyColor);
    Color c = renderer().selectionBackgroundColor();
    if (!c.alpha())
        return;

    // If the text color ends up being the same as the selection background, invert the selection
    // background.
    if (textColor == c)
        c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());

    GraphicsContextStateSaver stateSaver(*context);
    LayoutUnit top = root().selectionTop();
    LayoutUnit h = root().selectionHeight();
    const int deltaY = roundToInt(logicalTop() - top);
    const FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
    FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, h.toFloat()));
    context->clip(clipRect);
    context->drawHighlightForText(font, constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), localOrigin, h, c);
}
Ejemplo n.º 21
0
bool X11Helper::setLayout(const LayoutUnit& layout)
{
	QList<LayoutUnit> currentLayouts = getLayoutsList();
	int idx = currentLayouts.indexOf(layout);
	if( idx == -1 || idx >= X11Helper::MAX_GROUP_COUNT ) {
		qCWarning(KCM_KEYBOARD) << "Layout" << layout.toString() << "is not found in current layout list"
								<< getLayoutsListAsString(currentLayouts);
		return false;
	}

	return X11Helper::setGroup((unsigned int)idx);
}
Ejemplo n.º 22
0
const Shape& ShapeOutsideInfo::computedShape() const
{
    if (Shape* shape = m_shape.get())
        return *shape;

    const RenderStyle& style = *m_renderer.style();
    ASSERT(m_renderer.containingBlock());
    const RenderStyle& containingBlockStyle = *m_renderer.containingBlock()->style();

    WritingMode writingMode = containingBlockStyle.writingMode();
    LayoutUnit maximumValue = m_renderer.containingBlock() ? m_renderer.containingBlock()->contentWidth() : LayoutUnit();
    float margin = floatValueForLength(m_renderer.style()->shapeMargin(), maximumValue.toFloat());

    float shapeImageThreshold = style.shapeImageThreshold();
    ASSERT(style.shapeOutside());
    const ShapeValue& shapeValue = *style.shapeOutside();

    switch (shapeValue.type()) {
    case ShapeValue::Shape:
        ASSERT(shapeValue.shape());
        m_shape = Shape::createShape(shapeValue.shape(), m_referenceBoxLogicalSize, writingMode, margin);
        break;
    case ShapeValue::Image: {
        Image* image;
        LayoutRect imageRect;
        getShapeImageAndRect(shapeValue, m_renderer, m_referenceBoxLogicalSize, image, imageRect);
        const LayoutRect& marginRect = getShapeImageMarginRect(m_renderer, m_referenceBoxLogicalSize);
        m_shape = Shape::createRasterShape(image, shapeImageThreshold, imageRect, marginRect, writingMode, margin);
        break;
    }
    case ShapeValue::Box: {
        const RoundedRect& shapeRect = style.getRoundedBorderFor(LayoutRect(LayoutPoint(), m_referenceBoxLogicalSize), m_renderer.view());
        m_shape = Shape::createLayoutBoxShape(shapeRect, writingMode, margin);
        break;
    }
    }

    ASSERT(m_shape);
    return *m_shape;
}
Ejemplo n.º 23
0
void BackgroundImageGeometry::setSpaceY(LayoutUnit space,
                                        LayoutUnit availableHeight,
                                        LayoutUnit extraOffset) {
  LayoutUnit computedYPosition =
      roundedMinimumValueForLength(Length(), availableHeight);
  setSpaceSize(LayoutSize(spaceSize().width().toInt(), space.round()));
  LayoutUnit actualHeight = tileSize().height() + space;
  setPhaseY(actualHeight
                ? LayoutUnit(roundf(
                      actualHeight -
                      fmodf((computedYPosition + extraOffset), actualHeight)))
                : LayoutUnit());
}
Ejemplo n.º 24
0
LayoutPoint RenderRegion::mapRegionPointIntoFlowThreadCoordinates(const LayoutPoint& point)
{
    // Assuming the point is relative to the region block, 3 cases will be considered:
    // a) top margin, padding or border.
    // b) bottom margin, padding or border.
    // c) non-content region area.

    LayoutUnit pointLogicalTop(isHorizontalWritingMode() ? point.y() : point.x());
    LayoutUnit pointLogicalLeft(isHorizontalWritingMode() ? point.x() : point.y());
    LayoutUnit flowThreadLogicalTop(isHorizontalWritingMode() ? m_flowThreadPortionRect.y() : m_flowThreadPortionRect.x());
    LayoutUnit flowThreadLogicalLeft(isHorizontalWritingMode() ? m_flowThreadPortionRect.x() : m_flowThreadPortionRect.y());
    LayoutUnit flowThreadPortionTopBound(isHorizontalWritingMode() ? m_flowThreadPortionRect.height() : m_flowThreadPortionRect.width());
    LayoutUnit flowThreadPortionLeftBound(isHorizontalWritingMode() ? m_flowThreadPortionRect.width() : m_flowThreadPortionRect.height());
    LayoutUnit flowThreadPortionTopMax(isHorizontalWritingMode() ? m_flowThreadPortionRect.maxY() : m_flowThreadPortionRect.maxX());
    LayoutUnit flowThreadPortionLeftMax(isHorizontalWritingMode() ? m_flowThreadPortionRect.maxX() : m_flowThreadPortionRect.maxY());
    LayoutUnit effectiveFixedPointDenominator;
    effectiveFixedPointDenominator.setRawValue(1);

    if (pointLogicalTop < 0) {
        LayoutPoint pointInThread(0, flowThreadLogicalTop);
        return isHorizontalWritingMode() ? pointInThread : pointInThread.transposedPoint();
    }

    if (pointLogicalTop >= flowThreadPortionTopBound) {
        LayoutPoint pointInThread(flowThreadPortionLeftBound, flowThreadPortionTopMax - effectiveFixedPointDenominator);
        return isHorizontalWritingMode() ? pointInThread : pointInThread.transposedPoint();
    }

    if (pointLogicalLeft < 0) {
        LayoutPoint pointInThread(flowThreadLogicalLeft, pointLogicalTop + flowThreadLogicalTop);
        return isHorizontalWritingMode() ? pointInThread : pointInThread.transposedPoint();
    }
    if (pointLogicalLeft >= flowThreadPortionLeftBound) {
        LayoutPoint pointInThread(flowThreadPortionLeftMax - effectiveFixedPointDenominator, pointLogicalTop + flowThreadLogicalTop);
        return isHorizontalWritingMode() ? pointInThread : pointInThread.transposedPoint();
    }
    LayoutPoint pointInThread(pointLogicalLeft + flowThreadLogicalLeft, pointLogicalTop + flowThreadLogicalTop);
    return isHorizontalWritingMode() ? pointInThread : pointInThread.transposedPoint();
}
Ejemplo n.º 25
0
LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos)
{
    int sPos = max(startPos - m_start, 0);
    int ePos = min(endPos - m_start, (int)m_len);

    if (sPos > ePos)
        return LayoutRect();

    FontCachePurgePreventer fontCachePurgePreventer;

    LayoutUnit selTop = selectionTop();
    LayoutUnit selHeight = selectionHeight();
    RenderStyle* styleToUse = textRenderer().style(isFirstLineStyle());
    const Font& font = styleToUse->font();

    StringBuilder charactersWithHyphen;
    bool respectHyphen = ePos == m_len && hasHyphen();
    TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charactersWithHyphen : 0);

    FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop.toFloat());
    LayoutRect r;
    if (sPos || ePos != static_cast<int>(m_len))
        r = enclosingIntRect(font.selectionRectForText(textRun, startingPoint, selHeight, sPos, ePos));
    else // Avoid computing the font width when the entire line box is selected as an optimization.
        r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth, selHeight.toFloat())));

    LayoutUnit logicalWidth = r.width();
    if (r.x() > logicalRight())
        logicalWidth  = 0;
    else if (r.maxX() > logicalRight())
        logicalWidth = logicalRight() - r.x();

    LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutPoint(selTop, r.x());
    LayoutUnit width = isHorizontal() ? logicalWidth : selHeight;
    LayoutUnit height = isHorizontal() ? selHeight : logicalWidth;

    return LayoutRect(topPoint, LayoutSize(width, height));
}
Ejemplo n.º 26
0
LayoutRect RenderMathMLOperator::paintCharacter(PaintInfo& info, UChar character, const LayoutPoint& origin, CharacterPaintTrimming trim)
{
    GlyphData data = style()->font().glyphDataForCharacter(character, false);
    FloatRect glyphBounds = data.fontData->boundsForGlyph(data.glyph);

    LayoutRect glyphPaintRect(origin, LayoutSize(glyphBounds.x() + glyphBounds.width(), glyphBounds.height()));
    glyphPaintRect.setY(origin.y() + glyphBounds.y());

    // In order to have glyphs fit snugly with one another we snap the connecting edges to pixel boundaries
    // and trim off one pixel. The pixel trim is to account for fonts that have edge pixels that have less
    // than full coverage. These edge pixels can introduce small seams between connected glyphs
    FloatRect clipBounds = info.rect;
    switch (trim) {
    case TrimTop:
        glyphPaintRect.shiftYEdgeTo(glyphPaintRect.y().ceil() + 1);
        clipBounds.shiftYEdgeTo(glyphPaintRect.y());
        break;
    case TrimBottom:
        glyphPaintRect.shiftMaxYEdgeTo(glyphPaintRect.maxY().floor() - 1);
        clipBounds.shiftMaxYEdgeTo(glyphPaintRect.maxY());
        break;
    case TrimTopAndBottom:
        LayoutUnit temp = glyphPaintRect.y() + 1;
        glyphPaintRect.shiftYEdgeTo(temp.ceil());
        glyphPaintRect.shiftMaxYEdgeTo(glyphPaintRect.maxY().floor() - 1);
        clipBounds.shiftYEdgeTo(glyphPaintRect.y());
        clipBounds.shiftMaxYEdgeTo(glyphPaintRect.maxY());
        break;
    }

    // Clipping the enclosing IntRect avoids any potential issues at joined edges.
    GraphicsContextStateSaver stateSaver(*info.context);
    info.context->clip(clipBounds);

    info.context->drawText(style()->font(), TextRun(&character, 1), origin);

    return glyphPaintRect;
}
Ejemplo n.º 27
0
void MediaControls::notifyPanelWidthChanged(const LayoutUnit& newWidth) {
  // Don't bother to do any work if this matches the most recent panel
  // width, since we're called after layout.
  // Note that this code permits a bad frame on resize, since it is
  // run after the relayout / paint happens.  It would be great to improve
  // this, but it would be even greater to move this code entirely to
  // JS and fix it there.
  m_panelWidth = newWidth.toInt();

  // Adjust for effective zoom.
  if (!m_panel->layoutObject() || !m_panel->layoutObject()->style())
    return;
  m_panelWidth =
      ceil(m_panelWidth / m_panel->layoutObject()->style()->effectiveZoom());

  m_panelWidthChangedTimer.startOneShot(0, BLINK_FROM_HERE);
}
Ejemplo n.º 28
0
void distanceDataForNode(FocusType type, const FocusCandidate& current, FocusCandidate& candidate)
{
    if (areElementsOnSameLine(current, candidate)) {
        if ((type == FocusTypeUp && current.rect.y() > candidate.rect.y()) || (type == FocusTypeDown && candidate.rect.y() > current.rect.y())) {
            candidate.distance = 0;
            candidate.alignment = Full;
            return;
        }
    }

    LayoutRect nodeRect = candidate.rect;
    LayoutRect currentRect = current.rect;
    deflateIfOverlapped(currentRect, nodeRect);

    if (!isRectInDirection(type, currentRect, nodeRect))
        return;

    LayoutPoint exitPoint;
    LayoutPoint entryPoint;
    entryAndExitPointsForDirection(type, currentRect, nodeRect, exitPoint, entryPoint);

    LayoutUnit xAxis = exitPoint.x() - entryPoint.x();
    LayoutUnit yAxis = exitPoint.y() - entryPoint.y();

    LayoutUnit navigationAxisDistance;
    LayoutUnit orthogonalAxisDistance;

    switch (type) {
    case FocusTypeLeft:
    case FocusTypeRight:
        navigationAxisDistance = xAxis.abs();
        orthogonalAxisDistance = yAxis.abs();
        break;
    case FocusTypeUp:
    case FocusTypeDown:
        navigationAxisDistance = yAxis.abs();
        orthogonalAxisDistance = xAxis.abs();
        break;
    default:
        ASSERT_NOT_REACHED();
        return;
    }

    double euclidianDistancePow2 = (xAxis * xAxis + yAxis * yAxis).toDouble();
    LayoutRect intersectionRect = intersection(currentRect, nodeRect);
    double overlap = (intersectionRect.width() * intersectionRect.height()).toDouble();

    // Distance calculation is based on http://www.w3.org/TR/WICD/#focus-handling
    candidate.distance = sqrt(euclidianDistancePow2) + navigationAxisDistance+ orthogonalAxisDistance * 2 - sqrt(overlap);

    LayoutSize viewSize = candidate.visibleNode->document().page()->deprecatedLocalMainFrame()->view()->visibleContentRect().size();
    candidate.alignment = alignmentForRects(type, currentRect, nodeRect, viewSize);
}
Ejemplo n.º 29
0
QString Flags::getShortText(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig)
{
    if( layoutUnit.isEmpty() )
        return QString("--");

    QString layoutText = layoutUnit.layout;

    foreach(const LayoutUnit& lu, keyboardConfig.layouts) {
        if( layoutUnit.layout == lu.layout && layoutUnit.variant == lu.variant ) {
            layoutText = lu.getDisplayName();
            break;
        }
    }

//TODO: good autolabel
//	if( layoutText == layoutUnit.layout && layoutUnit.getDisplayName() != layoutUnit.layout ) {
//		layoutText = layoutUnit.getDisplayName();
//	}

    return layoutText;
}
Ejemplo n.º 30
0
const QIcon Flags::getIconWithText(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig)
{
    QString keySuffix(getPixmapKey(keyboardConfig));
    QString key(layoutUnit.toString() + keySuffix);
    if( iconOrTextMap.contains(key) ) {
        return iconOrTextMap[ key ];
    }

    if( keyboardConfig.indicatorType == KeyboardConfig::SHOW_FLAG ) {
        QIcon icon = getIcon(layoutUnit.layout);
        if( ! icon.isNull() ) {
            iconOrTextMap[ key ] = icon;
            return icon;
        }
    }

    QString layoutText = Flags::getShortText(layoutUnit, keyboardConfig);

    const QSize TRAY_ICON_SIZE(21, 14);
    QPixmap pixmap = QPixmap(TRAY_ICON_SIZE);
    pixmap.fill(Qt::transparent);

    QPainter painter(&pixmap);
//	p.setRenderHint(QPainter::SmoothPixmapTransform);
//	p.setRenderHint(QPainter::Antialiasing);

    if( keyboardConfig.indicatorType == KeyboardConfig::SHOW_LABEL_ON_FLAG ) {
        QIcon iconf = createIcon(layoutUnit.layout);
        iconf.paint(&painter, painter.window(), Qt::AlignCenter);
    }

    drawLabel(painter, layoutText, keyboardConfig.isFlagShown());

    painter.end();

    QIcon icon(pixmap);
    iconOrTextMap[ key ] = icon;

    return icon;
}