void PointLightSource::render(const UsefulRenderData& render_data)
{
  // If we are inside the sphere affected by the light source, render a full
  // quad. Otherwize just render the light sphere
  glm::vec4 position_world_space = glm::vec4(absoluteTransform()[3]);
  glm::vec3 position_view_space =
    glm::vec3(render_data.camera.viewTransform() * position_world_space);
  float distance_to_light_source = glm::length(position_view_space);
  
  // Probably not the best way of handling rescaled light sources,
  // but works for now..
  glm::vec3 scale;
  glm::quat rotation;
  glm::vec3 translation;
  glm::vec3 skew;
  glm::vec4 perspective;
  glm::decompose(
    absoluteTransform(), scale, rotation, translation, skew,perspective);
  float transform_scale = scale.x;

  if (distance_to_light_source < _sphere_scale * transform_scale)
    renderQuad(render_data);
  else
    renderSphere(render_data);
}
void RenderForeignObject::paint(PaintInfo& paintInfo, int parentX, int parentY)
{
    if (paintInfo.context->paintingDisabled())
        return;

    paintInfo.context->save();
    paintInfo.context->concatCTM(AffineTransform().translate(parentX, parentY));
    paintInfo.context->concatCTM(localTransform());
    paintInfo.context->concatCTM(translationForAttributes());
    paintInfo.context->clip(getClipRect(parentX, parentY));

    float opacity = style()->opacity();
    if (opacity < 1.0f)
        // FIXME: Possible optimization by clipping to bbox here, once relativeBBox is implemented & clip, mask and filter support added.
        paintInfo.context->beginTransparencyLayer(opacity);

    PaintInfo pi(paintInfo);
    pi.rect = absoluteTransform().inverse().mapRect(paintInfo.rect);
    RenderBlock::paint(pi, 0, 0);

    if (opacity < 1.0f)
        paintInfo.context->endTransparencyLayer();

    paintInfo.context->restore();
}
void PointLightSource::renderSphere(const UsefulRenderData& render_data)
{
  glm::mat4 scaled_transform = absoluteTransform();
  scaled_transform[0][0] *= _sphere_scale;
  scaled_transform[1][1] *= _sphere_scale;
  scaled_transform[2][2] *= _sphere_scale;

  glUniformMatrix4fv(
    glGetUniformLocation(ShaderProgram::currentProgramId(), "M"),
    1,
    GL_FALSE,
    &scaled_transform[0][0]);
  glUniformMatrix4fv(
      glGetUniformLocation(ShaderProgram::currentProgramId(), "V"),
      1,
      GL_FALSE,
      &render_data.camera.viewTransform()[0][0]);
  glUniformMatrix4fv(
      glGetUniformLocation(ShaderProgram::currentProgramId(), "P"),
      1,
      GL_FALSE,
      &render_data.camera.projectionTransform()[0][0]);

  setupLightSourceUniforms(render_data);

  _sphere_mesh->render();
}
IntRect RenderSVGInlineText::computeAbsoluteRectForRange(int startPos, int endPos)
{
    IntRect rect;

    RenderBlock* cb = containingBlock();
    if (!cb || !cb->container())
        return rect;

    RenderSVGRoot* root = findSVGRootObject(parent());
    if (!root)
        return rect;

    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
        rect.unite(box->selectionRect(0, 0, startPos, endPos));

    // Mimic RenderBox::computeAbsoluteRepaintRect() functionality. But only the subset needed for SVG and respecting SVG transformations.
    int x, y;
    cb->container()->absolutePosition(x, y);

    // Remove HTML parent translation offsets here! These need to be retrieved from the RenderSVGRoot object.
    // But do take the containingBlocks's container position into account, ie. SVG text in scrollable <div>.
    AffineTransform htmlParentCtm = root->RenderContainer::absoluteTransform();

    FloatRect fixedRect(narrowPrecisionToFloat(rect.x() + x - xPos() - htmlParentCtm.e()), narrowPrecisionToFloat(rect.y() + y - yPos() - htmlParentCtm.f()), rect.width(), rect.height());
    return enclosingIntRect(absoluteTransform().mapRect(fixedRect));
}
bool RenderForeignObject::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
{
    AffineTransform totalTransform = absoluteTransform();
    totalTransform *= translationForAttributes();
    double localX, localY;
    totalTransform.inverse().map(x, y, &localX, &localY);
    return RenderBlock::nodeAtPoint(request, result, static_cast<int>(localX), static_cast<int>(localY), tx, ty, hitTestAction);
}
Exemple #6
0
FloatPoint RenderPath::mapAbsolutePointToLocal(const FloatPoint& point) const
{
    // FIXME: does it make sense to map incoming points with the inverse of the
    // absolute transform?
    double localX;
    double localY;
    absoluteTransform().inverse().map(point.x(), point.y(), &localX, &localY);
    return FloatPoint::narrowPrecision(localX, localY);
}
Exemple #7
0
mat33
CameraNode::cameraTransform() {
    
    if(_absoluteTransformDirty) {
        _cameraTransform = AffineTransform::inverse(absoluteTransform());
    }
    
    return _cameraTransform;
}
bool RenderSVGText::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
{
    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, style()->svgStyle()->pointerEvents());
    bool isVisible = (style()->visibility() == VISIBLE);
    if (isVisible || !hitRules.requireVisible) {
        if ((hitRules.canHitStroke && (style()->svgStyle()->hasStroke() || !hitRules.requireStroke))
            || (hitRules.canHitFill && (style()->svgStyle()->hasFill() || !hitRules.requireFill))) {
            AffineTransform totalTransform = absoluteTransform();
            double localX, localY;
            totalTransform.inverse().map(_x, _y, &localX, &localY);
            FloatPoint hitPoint(_x, _y);
            return RenderBlock::nodeAtPoint(request, result, (int)localX, (int)localY, _tx, _ty, hitTestAction);
        }
    }
    return false;
}
Exemple #9
0
IntRect RenderSVGText::absoluteClippedOverflowRect()
{
    FloatRect repaintRect = absoluteTransform().mapRect(relativeBBox(true));

#if ENABLE(SVG_FILTERS)
    // Filters can expand the bounding box
    SVGResourceFilter* filter = getFilterById(document(), style()->svgStyle()->filter());
    if (filter)
        repaintRect.unite(filter->filterBBoxForItemBBox(repaintRect));
#endif

    if (!repaintRect.isEmpty())
        repaintRect.inflate(1); // inflate 1 pixel for antialiasing

    return enclosingIntRect(repaintRect);
}
std::pair<glm::vec3, glm::vec3> AbstractCamera::unproject(
  const glm::vec2& position_ndc) const
{
  // Transform from [-1, 1] to [0, 1]
  glm::vec2 position = position_ndc / 2.0f + glm::vec2(0.5);
  float w = 1, h = 1;

  const glm::mat4& V = glm::inverse(absoluteTransform());
  const glm::mat4& P = _projection_transform;
  
  glm::vec3 from =
    glm::unProject(glm::vec3(position, 0.0f), V, P, glm::vec4(0, 0, w, h));
  glm::vec3 to =
    glm::unProject(glm::vec3(position, 1.0f), V, P, glm::vec4(0, 0, w, h));
  
  return {from, to - from};
}
void RenderSVGImage::calculateAbsoluteBounds()
{
    // FIXME: broken with CSS transforms
    FloatRect absoluteRect = absoluteTransform().mapRect(relativeBBox(true));

#if ENABLE(SVG_FILTERS)
    // Filters can expand the bounding box
    SVGResourceFilter* filter = getFilterById(document(), style()->svgStyle()->filter());
    if (filter)
        absoluteRect.unite(filter->filterBBoxForItemBBox(absoluteRect));
#endif

    if (!absoluteRect.isEmpty())
        absoluteRect.inflate(1); // inflate 1 pixel for antialiasing

    m_absoluteBounds = enclosingIntRect(absoluteRect);
}
IntRect RenderSVGImage::absoluteClippedOverflowRect()
{
    FloatRect repaintRect = relativeBBox(true);
    repaintRect = absoluteTransform().mapRect(repaintRect);

#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
    // Filters can expand the bounding box
    SVGResourceFilter* filter = getFilterById(document(), SVGURIReference::getTarget(style()->svgStyle()->filter()));
    if (filter)
        repaintRect.unite(filter->filterBBoxForItemBBox(repaintRect));
#endif

    if (!repaintRect.isEmpty())
        repaintRect.inflate(1); // inflate 1 pixel for antialiasing

    return enclosingIntRect(repaintRect);
}
void PointLightSource::setupLightSourceUniforms(const UsefulRenderData& render_data)
{
  glm::vec4 position_world_space = glm::vec4(absoluteTransform()[3]);
  glm::vec4 position_view_space = render_data.camera.viewTransform() * position_world_space;

  glUniform3f(
    glGetUniformLocation(ShaderProgram::currentProgramId(),
      "light_source.position"),
    position_view_space.x, position_view_space.y, position_view_space.z);
  glUniform3f(
    glGetUniformLocation(ShaderProgram::currentProgramId(),
      "light_source.color"),
    _color.r, _color.g, _color.b);
  glUniform1f(
    glGetUniformLocation(ShaderProgram::currentProgramId(),
      "light_source.radiant_flux"),
    _radiant_flux);
}
Exemple #14
0
void RenderSVGTSpan::absoluteRects(Vector<IntRect>& rects, int, int, bool)
{
    InlineRunBox* firstBox = firstLineBox();

    SVGRootInlineBox* rootBox = firstBox ? static_cast<SVGInlineTextBox*>(firstBox)->svgRootInlineBox() : 0;
    RenderObject* object = rootBox ? rootBox->object() : 0;

    if (!object)
        return;

    int xRef = object->xPos() + xPos();
    int yRef = object->yPos() + yPos();
 
    for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
        FloatRect rect(xRef + curr->xPos(), yRef + curr->yPos(), curr->width(), curr->height());
        rects.append(enclosingIntRect(absoluteTransform().mapRect(rect)));
    }
}
void RenderSVGTextPath::absoluteRects(Vector<IntRect>& rects, int, int)
{
    InlineRunBox* firstBox = firstLineBox();

    SVGRootInlineBox* rootBox = firstBox ? static_cast<SVGInlineTextBox*>(firstBox)->svgRootInlineBox() : 0;
    RenderBlock* object = rootBox ? rootBox->block() : 0;

    if (!object)
        return;

    int xRef = object->x() + x();
    int yRef = object->y() + y();

    for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
        FloatRect rect(xRef + curr->xPos(), yRef + curr->yPos(), curr->width(), curr->height());
        // FIXME: broken with CSS transforms
        rects.append(enclosingIntRect(absoluteTransform().mapRect(rect)));
    }
}
Exemple #16
0
void RenderSVGTextPath::absoluteQuads(Vector<FloatQuad>& quads, bool)
{
    InlineRunBox* firstBox = firstLineBox();

    SVGRootInlineBox* rootBox = firstBox ? static_cast<SVGInlineTextBox*>(firstBox)->svgRootInlineBox() : 0;
    RenderObject* object = rootBox ? rootBox->object() : 0;

    if (!object)
        return;

    int xRef = object->xPos() + xPos();
    int yRef = object->yPos() + yPos();

    for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
        FloatRect rect(xRef + curr->xPos(), yRef + curr->yPos(), curr->width(), curr->height());
        // FIXME: broken with CSS transforms
        quads.append(absoluteTransform().mapRect(rect));
    }
}
IntRect RenderPath::clippedOverflowRectForRepaint(RenderBox* /*repaintContainer*/)
{
    // FIXME: handle non-root repaintContainer
    FloatRect repaintRect = absoluteTransform().mapRect(relativeBBox(true));

    // Markers can expand the bounding box
    repaintRect.unite(m_markerBounds);

#if ENABLE(SVG_FILTERS)
    // Filters can expand the bounding box
    SVGResourceFilter* filter = getFilterById(document(), style()->svgStyle()->filter());
    if (filter)
        repaintRect.unite(filter->filterBBoxForItemBBox(repaintRect));
#endif

    if (!repaintRect.isEmpty())
        repaintRect.inflate(1); // inflate 1 pixel for antialiasing

    return enclosingIntRect(repaintRect);
}
void DirectionalLightSource::setupLightSourceUniforms(const UsefulRenderData& render_data)
{
  glm::vec3 direction_model_space = glm::vec3(0.0f, -1.0f, 0.0f);
  glm::vec3 direction_world_space =
    glm::mat3(absoluteTransform()) * direction_model_space;
  glm::vec3 direction_view_space =
    glm::mat3(render_data.camera.viewTransform()) * direction_world_space;

  glUniform3f(
    glGetUniformLocation(ShaderProgram::currentProgramId(),
      "light_source.direction"),
    direction_view_space.x, direction_view_space.y, direction_view_space.z);
  glUniform3f(
    glGetUniformLocation(ShaderProgram::currentProgramId(),
      "light_source.color"),
    _color.r, _color.g, _color.b);
  glUniform1f(
    glGetUniformLocation(ShaderProgram::currentProgramId(),
      "light_source.radiance"),
    _radiance);
}
bool RenderSVGImage::nodeAtPoint(const HitTestRequest&, HitTestResult& result, int _x, int _y, int, int, HitTestAction hitTestAction)
{
    // We only draw in the forground phase, so we only hit-test then.
    if (hitTestAction != HitTestForeground)
        return false;

    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_IMAGE_HITTESTING, style()->pointerEvents());
    
    bool isVisible = (style()->visibility() == VISIBLE);
    if (isVisible || !hitRules.requireVisible) {
        double localX, localY;
        absoluteTransform().inverse().map(_x, _y, localX, localY);

        if (hitRules.canHitFill) {
            if (m_localBounds.contains(narrowPrecisionToFloat(localX), narrowPrecisionToFloat(localY))) {
                updateHitTestResult(result, IntPoint(_x, _y));
                return true;
            }
        }
    }

    return false;
}
Exemple #20
0
void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int, bool)
{
    RenderSVGRoot* root = findSVGRootObject(parent());
    if (!root)
        return;

    int x, y;
    absolutePosition(x, y);

    AffineTransform htmlParentCtm = root->RenderContainer::absoluteTransform();
 
    // Don't use relativeBBox here, as it's unites the selection rects. Makes it hard
    // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
    for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {
        ASSERT(runBox->isInlineFlowBox());

        InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
        for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
            FloatRect boxRect(box->xPos(), box->yPos(), box->width(), box->height());
            boxRect.move(narrowPrecisionToFloat(x - htmlParentCtm.e()), narrowPrecisionToFloat(y - htmlParentCtm.f()));
            rects.append(enclosingIntRect(absoluteTransform().mapRect(boxRect)));
        }
    }
}
IntRect RenderSVGText::absoluteClippedOverflowRect()
{
    return enclosingIntRect(absoluteTransform().mapRect(relativeBBox(true)));
}
void RenderSVGText::paint(PaintInfo& paintInfo, int, int)
{   
    RenderObject::PaintInfo pi(paintInfo);
    pi.rect = absoluteTransform().inverse().mapRect(pi.rect);
    RenderBlock::paint(pi, 0, 0);
}
void RenderSVGImage::paint(PaintInfo& paintInfo, int parentX, int parentY)
{
    if (paintInfo.context->paintingDisabled() || (paintInfo.phase != PaintPhaseForeground) || style()->visibility() == HIDDEN)
        return;
    
    paintInfo.context->save();
    paintInfo.context->concatCTM(AffineTransform().translate(parentX, parentY));
    paintInfo.context->concatCTM(localTransform());
    paintInfo.context->concatCTM(translationForAttributes());

    FloatRect boundingBox = FloatRect(0, 0, width(), height());

    SVGElement* svgElement = static_cast<SVGElement*>(element());
    ASSERT(svgElement && svgElement->document() && svgElement->isStyled());

    SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
    const SVGRenderStyle* svgStyle = style()->svgStyle();

    AtomicString filterId(SVGURIReference::getTarget(svgStyle->filter()));
    AtomicString clipperId(SVGURIReference::getTarget(svgStyle->clipPath()));
    AtomicString maskerId(SVGURIReference::getTarget(svgStyle->maskElement()));

#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
    SVGResourceFilter* filter = getFilterById(document(), filterId);
#endif
    SVGResourceClipper* clipper = getClipperById(document(), clipperId);
    SVGResourceMasker* masker = getMaskerById(document(), maskerId);

#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
    if (filter)
        filter->prepareFilter(paintInfo.context, boundingBox);
    else if (!filterId.isEmpty())
        svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
#endif

    if (clipper) {
        clipper->addClient(styledElement);
        clipper->applyClip(paintInfo.context, boundingBox);
    } else if (!clipperId.isEmpty())
        svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);

    if (masker) {
        masker->addClient(styledElement);
        masker->applyMask(paintInfo.context, boundingBox);
    } else if (!maskerId.isEmpty())
        svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);

    float opacity = style()->opacity();
    if (opacity < 1.0f) {
        paintInfo.context->clip(enclosingIntRect(boundingBox));
        paintInfo.context->beginTransparencyLayer(opacity);
    }

    PaintInfo pi(paintInfo);
    pi.rect = absoluteTransform().inverse().mapRect(pi.rect);

    SVGImageElement* imageElt = static_cast<SVGImageElement*>(node());

    FloatRect destRect(m_x, m_y, contentWidth(), contentHeight());
    FloatRect srcRect(0, 0, image()->width(), image()->height());

    if (imageElt->preserveAspectRatio()->align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
        adjustRectsForAspectRatio(destRect, srcRect, imageElt->preserveAspectRatio());

    paintInfo.context->drawImage(image(), destRect, srcRect);

#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
    if (filter)
        filter->applyFilter(paintInfo.context, boundingBox);
#endif

    if (opacity < 1.0f)
        paintInfo.context->endTransparencyLayer();

    paintInfo.context->restore();
}
glm::mat4 AbstractCamera::viewTransform() const
{
  return glm::inverse(absoluteTransform());
}
void RenderSVGInlineText::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool)
{
    FloatRect absoluteRect = absoluteTransform().mapRect(FloatRect(tx, ty, width(), height()));
    rects.append(enclosingIntRect(absoluteRect));
}