// Computes area of quads that are possibly non-rectangular. Can be easily extended to polygons. static inline float quadArea(const FloatQuad& quad) { return fabs(0.5 * (wedgeProduct(quad.p1(), quad.p2()) + wedgeProduct(quad.p2(), quad.p3()) + wedgeProduct(quad.p3(), quad.p4()) + wedgeProduct(quad.p4(), quad.p1()))); }
void PopupContainer::showInRect(const FloatQuad& controlPosition, const IntSize& controlSize, FrameView* v, int index) { // The controlSize is the size of the select box. It's usually larger than // we need. Subtract border size so that usually the container will be // displayed exactly the same width as the select box. listBox()->setBaseWidth(max(controlSize.width() - borderSize * 2, 0)); listBox()->updateFromElement(); // We set the selected item in updateFromElement(), and disregard the // index passed into this function (same as Webkit's PopupMenuWin.cpp) // FIXME: make sure this is correct, and add an assertion. // ASSERT(popupWindow(popup)->listBox()->selectedIndex() == index); // Save and convert the controlPosition to main window coords. Each point is converted separately // to window coordinates because the control could be in a transformed webview and then each point // would be transformed by a different delta. m_controlPosition.setP1(v->contentsToWindow(IntPoint(controlPosition.p1().x(), controlPosition.p1().y()))); m_controlPosition.setP2(v->contentsToWindow(IntPoint(controlPosition.p2().x(), controlPosition.p2().y()))); m_controlPosition.setP3(v->contentsToWindow(IntPoint(controlPosition.p3().x(), controlPosition.p3().y()))); m_controlPosition.setP4(v->contentsToWindow(IntPoint(controlPosition.p4().x(), controlPosition.p4().y()))); m_controlSize = controlSize; // Position at (0, 0) since the frameRect().location() is relative to the // parent WebWidget. setFrameRect(IntRect(IntPoint(), controlSize)); showPopup(v); }
void PrintTo(const FloatQuad& quad, std::ostream* os) { ScopedFloatFlags scope(*os); *os << "FloatQuad(" << "(" << quad.p1().x() << ", " << quad.p1().y() << "), " << "(" << quad.p2().x() << ", " << quad.p2().y() << "), " << "(" << quad.p3().x() << ", " << quad.p3().y() << "), " << "(" << quad.p4().x() << ", " << quad.p4().y() << "))"; }
void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium* targetSurface) { if (layer->renderSurface() && layer->renderSurface() != targetSurface) { layer->renderSurface()->draw(layer->getDrawRect()); return; } if (!layer->drawsContent()) return; if (layer->bounds().isEmpty()) { layer->unreserveContentsTexture(); return; } setScissorToRect(layer->scissorRect()); IntRect targetSurfaceRect = m_currentRenderSurface ? m_currentRenderSurface->contentRect() : m_defaultRenderSurface->contentRect(); IntRect scissorRect = layer->scissorRect(); if (!scissorRect.isEmpty()) targetSurfaceRect.intersect(scissorRect); // Check if the layer falls within the visible bounds of the page. IntRect layerRect = layer->getDrawRect(); bool isLayerVisible = targetSurfaceRect.intersects(layerRect); if (!isLayerVisible) { layer->unreserveContentsTexture(); return; } // FIXME: Need to take into account the commulative render surface transforms all the way from // the default render surface in order to determine visibility. TransformationMatrix combinedDrawMatrix = (layer->targetRenderSurface() ? layer->targetRenderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform()); if (!layer->doubleSided()) { FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds())); FloatQuad mappedLayer = combinedDrawMatrix.mapQuad(FloatQuad(layerRect)); FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1(); FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1(); FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0); FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0); FloatPoint3D zAxis = xAxis.cross(yAxis); if (zAxis.z() < 0) { layer->unreserveContentsTexture(); return; } } layer->draw(targetSurfaceRect); // Draw the debug border if there is one. layer->drawDebugBorder(); }
CCLayerQuad::CCLayerQuad(const FloatQuad& quad) { // Create edges. m_left = Edge(quad.p4(), quad.p1()); m_right = Edge(quad.p2(), quad.p3()); m_top = Edge(quad.p1(), quad.p2()); m_bottom = Edge(quad.p3(), quad.p4()); float sign = quad.isCounterclockwise() ? -1 : 1; m_left.scale(sign); m_right.scale(sign); m_top.scale(sign); m_bottom.scale(sign); }
void LayerRendererChromium::drawLayer(CCLayerImpl* layer, CCRenderSurface* targetSurface) { if (layer->renderSurface() && layer->renderSurface() != targetSurface) { layer->renderSurface()->draw(this, layer->getDrawRect()); layer->renderSurface()->releaseContentsTexture(); return; } if (!layer->drawsContent()) return; if (!layer->opacity()) return; if (layer->bounds().isEmpty()) return; IntRect targetSurfaceRect = layer->targetRenderSurface() ? layer->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect(); if (layer->usesLayerScissor()) { IntRect scissorRect = layer->scissorRect(); targetSurfaceRect.intersect(scissorRect); if (targetSurfaceRect.isEmpty()) return; setScissorToRect(scissorRect); } else GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleLayerRect(targetSurfaceRect, layer->bounds(), layer->contentBounds(), layer->drawTransform()); visibleLayerRect.move(toSize(layer->scrollPosition())); layer->setVisibleLayerRect(visibleLayerRect); // The layer should not be drawn if (1) it is not double-sided and (2) the back of the layer is facing the screen. // This second condition is checked by computing the transformed normal of the layer. if (!layer->doubleSided()) { FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds())); FloatQuad mappedLayer = layer->screenSpaceTransform().mapQuad(FloatQuad(layerRect)); FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1(); FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1(); FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0); FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0); FloatPoint3D zAxis = xAxis.cross(yAxis); if (zAxis.z() < 0) return; } layer->draw(this); // Draw the debug border if there is one. layer->drawDebugBorder(this); }
void LayerRendererChromium::drawTexturedQuad(const TransformationMatrix& drawMatrix, float width, float height, float opacity, const FloatQuad& quad, int matrixLocation, int alphaLocation, int quadLocation) { static float glMatrix[16]; TransformationMatrix renderMatrix = drawMatrix; // Apply a scaling factor to size the quad from 1x1 to its intended size. renderMatrix.scale3d(width, height, 1); // Apply the projection matrix before sending the transform over to the shader. toGLMatrix(&glMatrix[0], m_projectionMatrix * renderMatrix); GLC(m_context, m_context->uniformMatrix4fv(matrixLocation, false, &glMatrix[0], 1)); if (quadLocation != -1) { float point[8]; point[0] = quad.p1().x(); point[1] = quad.p1().y(); point[2] = quad.p2().x(); point[3] = quad.p2().y(); point[4] = quad.p3().x(); point[5] = quad.p3().y(); point[6] = quad.p4().x(); point[7] = quad.p4().y(); GLC(m_context, m_context->uniform2fv(quadLocation, point, 4)); } if (alphaLocation != -1) GLC(m_context, m_context->uniform1f(alphaLocation, opacity)); GLC(m_context, m_context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0)); }
static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpaceQuad, RenderObject* targetRenderer, RenderObject* compositedRenderer, FloatQuad& compositedSpaceQuad) { ASSERT(targetRenderer); ASSERT(compositedRenderer); for (unsigned i = 0; i < 4; ++i) { IntPoint point; switch (i) { case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; } point = targetRenderer->frame()->view()->contentsToWindow(point); point = compositedRenderer->frame()->view()->windowToContents(point); FloatPoint floatPoint = compositedRenderer->absoluteToLocal(point, UseTransforms); switch (i) { case 0: compositedSpaceQuad.setP1(floatPoint); break; case 1: compositedSpaceQuad.setP2(floatPoint); break; case 2: compositedSpaceQuad.setP3(floatPoint); break; case 3: compositedSpaceQuad.setP4(floatPoint); break; } } }
static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpaceQuad, LayoutObject* targetRenderer, const LayoutBoxModelObject* paintInvalidationContainer, FloatQuad& compositedSpaceQuad) { ASSERT(targetRenderer); ASSERT(paintInvalidationContainer); for (unsigned i = 0; i < 4; ++i) { IntPoint point; switch (i) { case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; } // FIXME: this does not need to be absolute, just in the paint invalidation container's space. point = targetRenderer->frame()->view()->contentsToRootFrame(point); point = paintInvalidationContainer->frame()->view()->rootFrameToContents(point); FloatPoint floatPoint = paintInvalidationContainer->absoluteToLocal(point, UseTransforms); DeprecatedPaintLayer::mapPointToPaintBackingCoordinates(paintInvalidationContainer, floatPoint); switch (i) { case 0: compositedSpaceQuad.setP1(floatPoint); break; case 1: compositedSpaceQuad.setP2(floatPoint); break; case 2: compositedSpaceQuad.setP3(floatPoint); break; case 3: compositedSpaceQuad.setP4(floatPoint); break; } } }
void InspectorTimelineAgent::localToPageQuad(const RenderObject& renderer, const LayoutRect& rect, FloatQuad* quad) { const FrameView& frameView = renderer.view().frameView(); FloatQuad absolute = renderer.localToAbsoluteQuad(FloatQuad(rect)); quad->setP1(frameView.contentsToRootView(roundedIntPoint(absolute.p1()))); quad->setP2(frameView.contentsToRootView(roundedIntPoint(absolute.p2()))); quad->setP3(frameView.contentsToRootView(roundedIntPoint(absolute.p3()))); quad->setP4(frameView.contentsToRootView(roundedIntPoint(absolute.p4()))); }
FloatQuad TransformationMatrix::projectQuad(const FloatQuad& q) const { FloatQuad projectedQuad; projectedQuad.setP1(projectPoint(q.p1())); projectedQuad.setP2(projectPoint(q.p2())); projectedQuad.setP3(projectPoint(q.p3())); projectedQuad.setP4(projectPoint(q.p4())); return projectedQuad; }
static PassRefPtr<InspectorArray> buildArrayForQuad(const FloatQuad& quad) { RefPtr<InspectorArray> array = InspectorArray::create(); array->pushObject(buildObjectForPoint(quad.p1())); array->pushObject(buildObjectForPoint(quad.p2())); array->pushObject(buildObjectForPoint(quad.p3())); array->pushObject(buildObjectForPoint(quad.p4())); return array.release(); }
static void addQuadToPath(const FloatQuad& quad, Path& path) { // FIXME: Make this create rounded quad-paths, just like the axis-aligned case. path.moveTo(quad.p1()); path.addLineTo(quad.p2()); path.addLineTo(quad.p3()); path.addLineTo(quad.p4()); path.closeSubpath(); }
static void localToPageQuad(const RenderObject& renderer, const LayoutRect& rect, FloatQuad* quad) { LocalFrame* frame = renderer.frame(); FrameView* view = frame->view(); FloatQuad absolute = renderer.localToAbsoluteQuad(FloatQuad(rect)); quad->setP1(view->contentsToRootView(roundedIntPoint(absolute.p1()))); quad->setP2(view->contentsToRootView(roundedIntPoint(absolute.p2()))); quad->setP3(view->contentsToRootView(roundedIntPoint(absolute.p3()))); quad->setP4(view->contentsToRootView(roundedIntPoint(absolute.p4()))); }
static Path quadToPath(const FloatQuad& quad) { Path quadPath; quadPath.moveTo(quad.p1()); quadPath.addLineTo(quad.p2()); quadPath.addLineTo(quad.p3()); quadPath.addLineTo(quad.p4()); quadPath.closeSubpath(); return quadPath; }
static void contentsQuadToCoordinateSystem(const FrameView* mainView, const FrameView* view, FloatQuad& quad, InspectorOverlay::CoordinateSystem coordinateSystem) { quad.setP1(view->contentsToRootView(roundedIntPoint(quad.p1()))); quad.setP2(view->contentsToRootView(roundedIntPoint(quad.p2()))); quad.setP3(view->contentsToRootView(roundedIntPoint(quad.p3()))); quad.setP4(view->contentsToRootView(roundedIntPoint(quad.p4()))); if (coordinateSystem == InspectorOverlay::CoordinateSystem::View) quad += mainView->scrollOffset(); }
static PassRefPtr<JSONArray> createQuad(const FloatQuad& quad) { RefPtr<JSONArray> array = JSONArray::create(); array->pushNumber(quad.p1().x()); array->pushNumber(quad.p1().y()); array->pushNumber(quad.p2().x()); array->pushNumber(quad.p2().y()); array->pushNumber(quad.p3().x()); array->pushNumber(quad.p3().y()); array->pushNumber(quad.p4().x()); array->pushNumber(quad.p4().y()); return array.release(); }
static PassRefPtr<InspectorArray> createQuad(const FloatQuad& quad) { RefPtr<InspectorArray> array = InspectorArray::create(); array->pushDouble(quad.p1().x()); array->pushDouble(quad.p1().y()); array->pushDouble(quad.p2().x()); array->pushDouble(quad.p2().y()); array->pushDouble(quad.p3().x()); array->pushDouble(quad.p3().y()); array->pushDouble(quad.p4().x()); array->pushDouble(quad.p4().y()); return array.release(); }
static Ref<InspectorArray> createQuad(const FloatQuad& quad) { Ref<InspectorArray> array = InspectorArray::create(); array->pushDouble(quad.p1().x()); array->pushDouble(quad.p1().y()); array->pushDouble(quad.p2().x()); array->pushDouble(quad.p2().y()); array->pushDouble(quad.p3().x()); array->pushDouble(quad.p3().y()); array->pushDouble(quad.p4().x()); array->pushDouble(quad.p4().y()); return WTF::move(array); }
FloatQuad TransformationMatrix::mapQuad(const FloatQuad& q) const { if (isIdentityOrTranslation()) { FloatQuad mappedQuad(q); mappedQuad.move(static_cast<float>(m_matrix[3][0]), static_cast<float>(m_matrix[3][1])); return mappedQuad; } FloatQuad result; result.setP1(mapPoint(q.p1())); result.setP2(mapPoint(q.p2())); result.setP3(mapPoint(q.p3())); result.setP4(mapPoint(q.p4())); return result; }
static FloatQuad projectQuad(const TransformationMatrix& transform, const FloatQuad& q, bool& clamped) { FloatQuad projectedQuad; bool clampedPoint; projectedQuad.setP1(transform.projectPoint(q.p1(), &clampedPoint)); clamped = clampedPoint; projectedQuad.setP2(transform.projectPoint(q.p2(), &clampedPoint)); clamped |= clampedPoint; projectedQuad.setP3(transform.projectPoint(q.p3(), &clampedPoint)); clamped |= clampedPoint; projectedQuad.setP4(transform.projectPoint(q.p4(), &clampedPoint)); clamped |= clampedPoint; return projectedQuad; }
FloatQuad AffineTransform::mapQuad(const FloatQuad& q) const { if (isIdentityOrTranslation()) { FloatQuad mappedQuad(q); mappedQuad.move(narrowPrecisionToFloat(m_transform[4]), narrowPrecisionToFloat(m_transform[5])); return mappedQuad; } FloatQuad result; result.setP1(mapPoint(q.p1())); result.setP2(mapPoint(q.p2())); result.setP3(mapPoint(q.p3())); result.setP4(mapPoint(q.p4())); return result; }
bool snapTo(const SubtargetGeometry& geom, const IntPoint& touchPoint, const IntRect& touchArea, IntPoint& adjustedPoint) { FrameView* view = geom.node()->document()->view(); FloatQuad quad = geom.quad(); if (quad.isRectilinear()) { IntRect contentBounds = geom.boundingBox(); // Convert from frame coordinates to window coordinates. IntRect bounds = view->contentsToWindow(contentBounds); if (bounds.contains(touchPoint)) { adjustedPoint = touchPoint; return true; } if (bounds.intersects(touchArea)) { bounds.intersect(touchArea); adjustedPoint = bounds.center(); return true; } return false; } // The following code tries to adjust the point to place inside a both the touchArea and the non-rectilinear quad. // FIXME: This will return the point inside the touch area that is the closest to the quad center, but does not // guarantee that the point will be inside the quad. Corner-cases exist where the quad will intersect but this // will fail to adjust the point to somewhere in the intersection. // Convert quad from content to window coordinates. FloatPoint p1 = contentsToWindow(view, quad.p1()); FloatPoint p2 = contentsToWindow(view, quad.p2()); FloatPoint p3 = contentsToWindow(view, quad.p3()); FloatPoint p4 = contentsToWindow(view, quad.p4()); quad = FloatQuad(p1, p2, p3, p4); if (quad.containsPoint(touchPoint)) { adjustedPoint = touchPoint; return true; } // Pull point towards the center of the element. FloatPoint center = quad.center(); adjustPointToRect(center, touchArea); adjustedPoint = roundedIntPoint(center); return quad.containsPoint(adjustedPoint); }
// Note that we only handle convex quads here. bool FloatQuad::containsQuad(const FloatQuad& other) const { return containsPoint(other.p1()) && containsPoint(other.p2()) && containsPoint(other.p3()) && containsPoint(other.p4()); }