<commit_before>#include "oglWidget.h"
#include <iostream>
//
// CONSTRUCTORS ////////////////////////////////////////////////////////////////
//

/**
 * @brief      Default constructor for OGLWidget.
 */
OGLWidget::OGLWidget()
{
    // Update the widget after a frameswap
    connect( this, SIGNAL( frameSwapped() ),
        this, SLOT( update() ) );

    // Allows keyboard input to fall through
    setFocusPolicy( Qt::ClickFocus );

    camera.rotate( -90.0f, 1.0f, 0.0f, 0.0f );
    camera.translate( 30.0f, 75.0f, 30.0f );

    renderables["Labyrinth"] = new Labyrinth( Environment::Ice, 10, 30, 30 );
    renderables["Ball"] = new Ball();
}

/**
 * @brief      Destructor class to unallocate OpenGL information.
 */
OGLWidget::~OGLWidget()
{
    makeCurrent();
    teardownGL();
    teardownBullet();
}

//
// OPENGL FUNCTIONS ////////////////////////////////////////////////////////////
//

/**
 * @brief      Initializes any OpenGL operations.
 */
void OGLWidget::initializeGL()
{
    // Init OpenGL Backend
    initializeOpenGLFunctions();
    printContextInfo();
    initializeBullet();

    for( QMap<QString, Renderable*>::iterator iter = renderables.begin();
        iter != renderables.end(); iter++ )
    {
        (*iter)->initializeGL();
    }

    ((Labyrinth*)renderables["Labyrinth"])->addRigidBodys( m_dynamicsWorld );
    m_dynamicsWorld->addRigidBody(
        ((Ball*)renderables["Ball"])->RigidBody
    );
}

/**
 * @brief      Sets the prespective whenever the window is resized.
 *
 * @param[in]  width   The width of the new window.
 * @param[in]  height  The height of the new window.
 */
void OGLWidget::resizeGL( int width, int height )
{
    projection.setToIdentity();
    projection.perspective( 55.0f,  // Field of view angle
                            float( width ) / float( height ),   // Aspect Ratio
                            0.001f,  // Near Plane (MUST BE GREATER THAN 0)
                            1500.0f );  // Far Plane
}

/**
 * @brief      OpenGL function to draw elements to the surface.
 */
void OGLWidget::paintGL()
{
    // Set the default OpenGL states
    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LEQUAL );
    glDepthMask( GL_TRUE );
    glEnable( GL_CULL_FACE );
    glClearColor( 0.0f, 0.0f, 0.2f, 1.0f );

    // Clear the screen
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    for( QMap<QString, Renderable*>::iterator iter = renderables.begin();
        iter != renderables.end(); iter++ )
    {
        (*iter)->paintGL( camera, projection );
    }
}

/**
 * @brief      Destroys any OpenGL data.
 */
void OGLWidget::teardownGL()
{
    for( QMap<QString, Renderable*>::iterator iter = renderables.begin();
        iter != renderables.end(); iter++ )
    {
        (*iter)->teardownGL();
    }
}

//
// SLOTS ///////////////////////////////////////////////////////////////////////
//

/**
 * @brief      Updates any user interactions and model transformations.
 */
void OGLWidget::update()
{
    float dt = updateTimer.deltaTime();
    Input::update();
    flyThroughCamera();

    // not sure what to call this method
    controlBoard();

    for( QMap<QString, Renderable*>::iterator iter = renderables.begin();
        iter != renderables.end(); iter++ )
    {
        (*iter)->update();
    }

    m_dynamicsWorld->stepSimulation( dt, 10 );
    QOpenGLWidget::update();
}

//
// INPUT EVENTS ////////////////////////////////////////////////////////////////
//

/**
 * @brief      Default slot for handling key press events.
 *
 * @param      event  The key event information.
 */
void OGLWidget::keyPressEvent( QKeyEvent* event )
{
    if( event->isAutoRepeat() )
        event->ignore();
    else
        Input::registerKeyPress( event->key() );
}

/**
 * @brief      Default slot for handling key release events.
 *
 * @param      event  The key event information.
 */
void OGLWidget::keyReleaseEvent( QKeyEvent* event )
{
    if( event->isAutoRepeat() )
        event->ignore();
    else
        Input::registerKeyRelease( event->key() );
}

/**
 * @brief      Default slot for handling mouse press events.
 *
 * @param      event  The mouse event information.
 */
void OGLWidget::mousePressEvent( QMouseEvent* event )
{
    Input::registerMousePress( event->button() );
}

/**
 * @brief      Default slot for handling mouse release events.
 *
 * @param      event  The mouse event information.
 */
void OGLWidget::mouseReleaseEvent( QMouseEvent* event )
{
    Input::registerMouseRelease( event->button() );
}

//
// PRIVATE HELPER FUNCTIONS ////////////////////////////////////////////////////
//

/**
 * @brief      Helper function to initialize bullet data.
 */
void OGLWidget::initializeBullet()
{
    m_broadphase = new btDbvtBroadphase();
    m_collisionConfig = new btDefaultCollisionConfiguration();
    m_dispatcher = new btCollisionDispatcher( m_collisionConfig );
    m_solver = new btSequentialImpulseConstraintSolver();
    m_dynamicsWorld = new btDiscreteDynamicsWorld( m_dispatcher, m_broadphase,
        m_solver, m_collisionConfig );
    m_dynamicsWorld->setGravity( btVector3( 0, -9.8, 0 ) );
}

/**
 * @brief      Helper function to delete bullet allocations.
 */
void OGLWidget::teardownBullet()
{
    delete m_dynamicsWorld;
    delete m_solver;
    delete m_dispatcher;
    delete m_collisionConfig;
    delete m_broadphase;
}

/**
 * @brief      Updates the main camera to behave like a Fly-Through Camera.
 */
void OGLWidget::flyThroughCamera()
{
    static const float cameraTranslationSpeed = 0.02f;
    static const float cameraRotationSpeed = 0.1f;

    if( Input::buttonPressed( Qt::RightButton ) )
    {
        // Rotate the camera based on mouse movement
        camera.rotate( -cameraRotationSpeed * Input::mouseDelta().x(),
            Camera3D::LocalUp );
        camera.rotate( -cameraRotationSpeed * Input::mouseDelta().y(),
            camera.right() );
    }

    // Translate the camera based on keyboard input
    QVector3D cameraTranslations;
    if( Input::keyPressed( Qt::Key_W ) )
        cameraTranslations += camera.forward();
    if( Input::keyPressed( Qt::Key_S ) )
        cameraTranslations -= camera.forward();
    if( Input::keyPressed( Qt::Key_A ) )
        cameraTranslations -= camera.right();
    if( Input::keyPressed( Qt::Key_D ) )
        cameraTranslations += camera.right();
    if( Input::keyPressed( Qt::Key_Q ) )
        cameraTranslations -= camera.up();
    if( Input::keyPressed( Qt::Key_E ) )
        cameraTranslations += camera.up();
    camera.translate( cameraTranslationSpeed * cameraTranslations );
}

/**
 * @brief      Updates board based on user input.
 */
void OGLWidget::controlBoard()
{
    const float rotationSpeed = 0.5f;
    const float rollingSpeed = 1.0f;
    btVector3 gravity = m_dynamicsWorld->getGravity();

    /* I suppose gravity being relative to camera would be best, here is some code incase you want
    to figure out a good way to do it.

    float cameraAngle;
    QVector3D cameraAxis;
    camera.rotation().getAxisAndAngle( &cameraAxis, &cameraAngle );
    //std::cout << cameraAngle << std::endl;
    //std::cout << cameraAxis.x() << std::endl;
    */

    if( Input::keyPressed( Qt::Key_Z ) )
    {
        // Update horizontal rotation
        if( Input::keyPressed( Qt::Key_Left ) )
        {
            camera.rotate( -rotationSpeed, QVector3D(0, 0, 1) );
            gravity -= btVector3( rollingSpeed, 0, 0 );
        }

        else if( Input::keyPressed( Qt::Key_Right ) )
        {
            camera.rotate( rotationSpeed, QVector3D(0, 0, 1) );
            gravity += btVector3( rollingSpeed, 0, 0 );
        }

        // Update vertical rotation
        if( Input::keyPressed( Qt::Key_Up ) )
        {
            camera.rotate( rotationSpeed, QVector3D(1, 0, 0) );
            gravity -= btVector3( 0, 0, rollingSpeed );
        }

        else if( Input::keyPressed( Qt::Key_Down ) )
        {
            camera.rotate( -rotationSpeed, QVector3D(1, 0, 0) );
            gravity += btVector3( 0, 0, rollingSpeed );
        }
    }

    else
    {
        // Update horizontal rotation
        if( Input::keyPressed( Qt::Key_Left ) )
        {
            camera.rotate( rotationSpeed, QVector3D(0, 0, 1) );
            gravity -= btVector3( rollingSpeed, 0, 0 );
        }

        else if( Input::keyPressed( Qt::Key_Right ) )
        {
            camera.rotate( -rotationSpeed, QVector3D(0, 0, 1) );
            gravity += btVector3( rollingSpeed, 0, 0 );
        }

        // Update vertical rotation
        if( Input::keyPressed( Qt::Key_Up ) )
        {
            camera.rotate( -rotationSpeed, QVector3D(1, 0, 0) );
            gravity -= btVector3( 0, 0, rollingSpeed );
        }

        else if( Input::keyPressed( Qt::Key_Down ) )
        {
            camera.rotate( rotationSpeed, QVector3D(1, 0, 0) );
            gravity += btVector3( 0, 0, rollingSpeed );
        }
    }

    // Update gravity
    m_dynamicsWorld->setGravity( gravity );

}
/**
 * @brief      Helper function to print OpenGL Context information to the debug.
 */
void OGLWidget::printContextInfo()
{
    QString glType;
    QString glVersion;
    QString glProfile;

    // Get Version Information
    glType = ( context()->isOpenGLES() ) ? "OpenGL ES" : "OpenGL";
    glVersion = reinterpret_cast<const char*>( glGetString( GL_VERSION ) );

    // Get Profile Information
    switch( format().profile() )
    {
        case QSurfaceFormat::NoProfile:
            glProfile = "No Profile";
            break;
        case QSurfaceFormat::CoreProfile:
            glProfile = "Core Profile";
            break;
        case QSurfaceFormat::CompatibilityProfile:
            glProfile = "Compatibility Profile";
            break;
    }

    qDebug() << qPrintable( glType ) << qPrintable( glVersion ) <<
        "(" << qPrintable( glProfile ) << ")";
}<commit_msg>Camera now moves with rotation, removed inverted option<commit_after>#include "oglWidget.h"
#include <iostream>
//
// CONSTRUCTORS ////////////////////////////////////////////////////////////////
//

/**
 * @brief      Default constructor for OGLWidget.
 */
OGLWidget::OGLWidget()
{
    // Update the widget after a frameswap
    connect( this, SIGNAL( frameSwapped() ),
        this, SLOT( update() ) );

    // Allows keyboard input to fall through
    setFocusPolicy( Qt::ClickFocus );

    camera.rotate( -90.0f, 1.0f, 0.0f, 0.0f );
    camera.translate( 30.0f, 75.0f, 30.0f );

    renderables["Labyrinth"] = new Labyrinth( Environment::Ice, 10, 30, 30 );
    renderables["Ball"] = new Ball();
}

/**
 * @brief      Destructor class to unallocate OpenGL information.
 */
OGLWidget::~OGLWidget()
{
    makeCurrent();
    teardownGL();
    teardownBullet();
}

//
// OPENGL FUNCTIONS ////////////////////////////////////////////////////////////
//

/**
 * @brief      Initializes any OpenGL operations.
 */
void OGLWidget::initializeGL()
{
    // Init OpenGL Backend
    initializeOpenGLFunctions();
    printContextInfo();
    initializeBullet();

    for( QMap<QString, Renderable*>::iterator iter = renderables.begin();
        iter != renderables.end(); iter++ )
    {
        (*iter)->initializeGL();
    }

    ((Labyrinth*)renderables["Labyrinth"])->addRigidBodys( m_dynamicsWorld );
    m_dynamicsWorld->addRigidBody(
        ((Ball*)renderables["Ball"])->RigidBody
    );
}

/**
 * @brief      Sets the prespective whenever the window is resized.
 *
 * @param[in]  width   The width of the new window.
 * @param[in]  height  The height of the new window.
 */
void OGLWidget::resizeGL( int width, int height )
{
    projection.setToIdentity();
    projection.perspective( 55.0f,  // Field of view angle
                            float( width ) / float( height ),   // Aspect Ratio
                            0.001f,  // Near Plane (MUST BE GREATER THAN 0)
                            1500.0f );  // Far Plane
}

/**
 * @brief      OpenGL function to draw elements to the surface.
 */
void OGLWidget::paintGL()
{
    // Set the default OpenGL states
    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LEQUAL );
    glDepthMask( GL_TRUE );
    glEnable( GL_CULL_FACE );
    glClearColor( 0.0f, 0.0f, 0.2f, 1.0f );

    // Clear the screen
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    for( QMap<QString, Renderable*>::iterator iter = renderables.begin();
        iter != renderables.end(); iter++ )
    {
        (*iter)->paintGL( camera, projection );
    }
}

/**
 * @brief      Destroys any OpenGL data.
 */
void OGLWidget::teardownGL()
{
    for( QMap<QString, Renderable*>::iterator iter = renderables.begin();
        iter != renderables.end(); iter++ )
    {
        (*iter)->teardownGL();
    }
}

//
// SLOTS ///////////////////////////////////////////////////////////////////////
//

/**
 * @brief      Updates any user interactions and model transformations.
 */
void OGLWidget::update()
{
    float dt = updateTimer.deltaTime();
    Input::update();
    flyThroughCamera();

    // not sure what to call this method
    controlBoard();

    for( QMap<QString, Renderable*>::iterator iter = renderables.begin();
        iter != renderables.end(); iter++ )
    {
        (*iter)->update();
    }

    m_dynamicsWorld->stepSimulation( dt, 10 );
    QOpenGLWidget::update();
}

//
// INPUT EVENTS ////////////////////////////////////////////////////////////////
//

/**
 * @brief      Default slot for handling key press events.
 *
 * @param      event  The key event information.
 */
void OGLWidget::keyPressEvent( QKeyEvent* event )
{
    if( event->isAutoRepeat() )
        event->ignore();
    else
        Input::registerKeyPress( event->key() );
}

/**
 * @brief      Default slot for handling key release events.
 *
 * @param      event  The key event information.
 */
void OGLWidget::keyReleaseEvent( QKeyEvent* event )
{
    if( event->isAutoRepeat() )
        event->ignore();
    else
        Input::registerKeyRelease( event->key() );
}

/**
 * @brief      Default slot for handling mouse press events.
 *
 * @param      event  The mouse event information.
 */
void OGLWidget::mousePressEvent( QMouseEvent* event )
{
    Input::registerMousePress( event->button() );
}

/**
 * @brief      Default slot for handling mouse release events.
 *
 * @param      event  The mouse event information.
 */
void OGLWidget::mouseReleaseEvent( QMouseEvent* event )
{
    Input::registerMouseRelease( event->button() );
}

//
// PRIVATE HELPER FUNCTIONS ////////////////////////////////////////////////////
//

/**
 * @brief      Helper function to initialize bullet data.
 */
void OGLWidget::initializeBullet()
{
    m_broadphase = new btDbvtBroadphase();
    m_collisionConfig = new btDefaultCollisionConfiguration();
    m_dispatcher = new btCollisionDispatcher( m_collisionConfig );
    m_solver = new btSequentialImpulseConstraintSolver();
    m_dynamicsWorld = new btDiscreteDynamicsWorld( m_dispatcher, m_broadphase,
        m_solver, m_collisionConfig );
    m_dynamicsWorld->setGravity( btVector3( 0, -9.8, 0 ) );
}

/**
 * @brief      Helper function to delete bullet allocations.
 */
void OGLWidget::teardownBullet()
{
    delete m_dynamicsWorld;
    delete m_solver;
    delete m_dispatcher;
    delete m_collisionConfig;
    delete m_broadphase;
}

/**
 * @brief      Updates the main camera to behave like a Fly-Through Camera.
 */
void OGLWidget::flyThroughCamera()
{
    static const float cameraTranslationSpeed = 0.02f;
    static const float cameraRotationSpeed = 0.1f;

    if( Input::buttonPressed( Qt::RightButton ) )
    {
        // Rotate the camera based on mouse movement
        camera.rotate( -cameraRotationSpeed * Input::mouseDelta().x(),
            Camera3D::LocalUp );
        camera.rotate( -cameraRotationSpeed * Input::mouseDelta().y(),
            camera.right() );
    }

    // Translate the camera based on keyboard input
    QVector3D cameraTranslations;
    if( Input::keyPressed( Qt::Key_W ) )
        cameraTranslations += camera.forward();
    if( Input::keyPressed( Qt::Key_S ) )
        cameraTranslations -= camera.forward();
    if( Input::keyPressed( Qt::Key_A ) )
        cameraTranslations -= camera.right();
    if( Input::keyPressed( Qt::Key_D ) )
        cameraTranslations += camera.right();
    if( Input::keyPressed( Qt::Key_Q ) )
        cameraTranslations -= camera.up();
    if( Input::keyPressed( Qt::Key_E ) )
        cameraTranslations += camera.up();
    camera.translate( cameraTranslationSpeed * cameraTranslations );
}

/**
 * @brief      Updates board based on user input.
 */
void OGLWidget::controlBoard()
{
    const float rotationSpeed = 0.5f;
    const float rollingSpeed = 1.0f;
    btVector3 gravity = m_dynamicsWorld->getGravity();

    /* I suppose gravity being relative to camera would be best, here is some code incase you want
    to figure out a good way to do it.

    float cameraAngle;
    QVector3D cameraAxis;
    camera.rotation().getAxisAndAngle( &cameraAxis, &cameraAngle );
    //std::cout << cameraAngle << std::endl;
    //std::cout << cameraAxis.x() << std::endl;
    */

    // Update horizontal rotation
    if( Input::keyPressed( Qt::Key_Left ) )
    {
        camera.rotate( -rotationSpeed, QVector3D(0, 0, 1) );
        camera.translate( 0.5f, 0, 0);
        gravity -= btVector3( rollingSpeed, 0, 0 );
    }

    else if( Input::keyPressed( Qt::Key_Right ) )
    {
        camera.rotate( rotationSpeed, QVector3D(0, 0, 1) );
        camera.translate( -0.5f, 0, 0);
        gravity += btVector3( rollingSpeed, 0, 0 );
    }

    // Update vertical rotation
    if( Input::keyPressed( Qt::Key_Up ) )
    {
        camera.rotate( rotationSpeed, QVector3D(1, 0, 0) );
        camera.translate( 0, 0, 0.75f );
        gravity -= btVector3( 0, 0, rollingSpeed );
    }

    else if( Input::keyPressed( Qt::Key_Down ) )
    {
        camera.rotate( -rotationSpeed, QVector3D(1, 0, 0) );
        camera.translate( 0, 0, -0.75f );
        gravity += btVector3( 0, 0, rollingSpeed );
    }

    // Update gravity
    m_dynamicsWorld->setGravity( gravity );

}
/**
 * @brief      Helper function to print OpenGL Context information to the debug.
 */
void OGLWidget::printContextInfo()
{
    QString glType;
    QString glVersion;
    QString glProfile;

    // Get Version Information
    glType = ( context()->isOpenGLES() ) ? "OpenGL ES" : "OpenGL";
    glVersion = reinterpret_cast<const char*>( glGetString( GL_VERSION ) );

    // Get Profile Information
    switch( format().profile() )
    {
        case QSurfaceFormat::NoProfile:
            glProfile = "No Profile";
            break;
        case QSurfaceFormat::CoreProfile:
            glProfile = "Core Profile";
            break;
        case QSurfaceFormat::CompatibilityProfile:
            glProfile = "Compatibility Profile";
            break;
    }

    qDebug() << qPrintable( glType ) << qPrintable( glVersion ) <<
        "(" << qPrintable( glProfile ) << ")";
}<|endoftext|>


<commit_before>//
// EigenJS.cpp
// ~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot com)
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#ifndef EIGENJS_COMPLEX_HPP
#define EIGENJS_COMPLEX_HPP

#include <node.h>
#include <v8.h>

#include <nan.h>

#include <complex>
#include <sstream>

#define EIGENJS_COMPLEX_CLASS_METHOD( NAME )                                  \
  static NAN_METHOD( NAME ) {                                                 \
    NanScope();                                                               \
                                                                              \
    if ( args.Length() == 1 && HasInstance(args[0]) ) {                       \
      const Complex* obj =                                                    \
          node::ObjectWrap::Unwrap<Complex>( args[0]->ToObject() );           \
                                                                              \
      const complex_type& NAME = std::NAME( obj->complex_ );                  \
      const element_type& real = NAME.real();                                 \
      const element_type& imag = NAME.imag();                                 \
                                                                              \
      v8::Local<v8::Function> ctor = NanNew( constructor );                   \
      v8::Local<v8::Value> argv[] = {                                         \
          NanNew<v8::Number>( real )                                          \
        , NanNew<v8::Number>( imag )                                          \
      };                                                                      \
                                                                              \
      v8::Local<v8::Object> new_complex = ctor->NewInstance(                  \
          sizeof( argv ) / sizeof( v8::Local<v8::Value> )                     \
        , argv                                                                \
      );                                                                      \
                                                                              \
      NanReturnValue( new_complex );                                          \
    }                                                                         \
                                                                              \
    NanReturnUndefined();                                                     \
  }                                                                           \
/**/

namespace EigenJS {

template <typename ValueType>
class Complex : public node::ObjectWrap {
  typedef ValueType element_type;
  typedef std::complex<element_type> complex_type;

 public:
  static void Init(v8::Handle<v8::Object> exports) {
    NanScope();

    v8::Local<v8::FunctionTemplate> tpl = NanNew<v8::FunctionTemplate>(New);
    tpl->SetClassName(NanNew("Complex"));
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    NODE_SET_PROTOTYPE_METHOD(tpl, "abs", abs);
    NODE_SET_PROTOTYPE_METHOD(tpl, "arg", arg);
    NODE_SET_PROTOTYPE_METHOD(tpl, "norm", norm);
    NODE_SET_PROTOTYPE_METHOD(tpl, "conj", conj);

    NODE_SET_METHOD(tpl, "polar", polar);
    NODE_SET_METHOD(tpl, "proj", proj);

    NODE_SET_METHOD(tpl, "cos", cos);
    NODE_SET_METHOD(tpl, "cosh", cosh);
    NODE_SET_METHOD(tpl, "exp", exp);
    NODE_SET_METHOD(tpl, "log", log);
    NODE_SET_METHOD(tpl, "log10", log10);
    NODE_SET_METHOD(tpl, "pow", pow);
    NODE_SET_METHOD(tpl, "sin", sin);
    NODE_SET_METHOD(tpl, "sinh", sinh);
    NODE_SET_METHOD(tpl, "sqrt", sqrt);
    NODE_SET_METHOD(tpl, "tan", tan);
    NODE_SET_METHOD(tpl, "tanh", tanh);
    NODE_SET_METHOD(tpl, "acos", acos);
    NODE_SET_METHOD(tpl, "acosh", acosh);

    NODE_SET_PROTOTYPE_METHOD(tpl, "toString", toString);

    v8::Local<v8::ObjectTemplate> proto = tpl->PrototypeTemplate();
    proto->SetAccessor(NanNew("real"), get_real, set_real);
    proto->SetAccessor(NanNew("imag"), get_imag, set_imag);

    NanAssignPersistent(constructor, tpl->GetFunction());
    exports->Set(NanNew("Complex"), tpl->GetFunction());

    NanAssignPersistent(function_template, tpl);
  }

  static NAN_METHOD(abs) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::abs(obj->complex_)));
  }

  static NAN_METHOD(arg) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::arg(obj->complex_)));
  }

  static NAN_METHOD(norm) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::norm(obj->complex_)));
  }

  static NAN_METHOD(conj) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    const complex_type& c = std::conj(obj->complex_);
    const element_type& real = c.real();
    const element_type& imag = c.imag();
    NanScope();

    v8::Local<v8::Function> ctor = NanNew(constructor);
    v8::Local<v8::Value> argv[] = {
        NanNew<v8::Number>(real)
      , NanNew<v8::Number>(imag)
    };

    v8::Local<v8::Object> new_complex = ctor->NewInstance(
        sizeof(argv) / sizeof(v8::Local<v8::Value>)
      , argv
    );

    NanReturnValue(new_complex);
  }

  static NAN_METHOD(polar) {
    NanScope();

    if (args.Length() == 2 &&
        args[0]->IsNumber() &&
        args[1]->IsNumber()) {
      const element_type& rho = args[0]->NumberValue();
      const element_type& theta = args[1]->NumberValue();

      v8::Local<v8::Function> ctor = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {
          NanNew<v8::Number>(rho)
        , NanNew<v8::Number>(theta)
      };

      v8::Local<v8::Object> new_complex = ctor->NewInstance(
          sizeof(argv) / sizeof(v8::Local<v8::Value>)
        , argv
      );

      NanReturnValue(new_complex);
    }

    NanReturnUndefined();
  }

  EIGENJS_COMPLEX_CLASS_METHOD(proj)
  EIGENJS_COMPLEX_CLASS_METHOD(cos)
  EIGENJS_COMPLEX_CLASS_METHOD(cosh)
  EIGENJS_COMPLEX_CLASS_METHOD(exp)
  EIGENJS_COMPLEX_CLASS_METHOD(log)
  EIGENJS_COMPLEX_CLASS_METHOD(log10)
  EIGENJS_COMPLEX_CLASS_METHOD(sin)
  EIGENJS_COMPLEX_CLASS_METHOD(sinh)
  EIGENJS_COMPLEX_CLASS_METHOD(sqrt)
  EIGENJS_COMPLEX_CLASS_METHOD(tan)
  EIGENJS_COMPLEX_CLASS_METHOD(tanh)
  EIGENJS_COMPLEX_CLASS_METHOD(acos)
  EIGENJS_COMPLEX_CLASS_METHOD(acosh)

  static NAN_METHOD(pow) {
    NanScope();

    if (args.Length() == 2 &&
        is_complex_or_saclar(args[0]) &&
        is_complex_or_saclar(args[1])) {
      const bool& arg0_is_complex = is_complex(args[0]);
      const bool& arg1_is_complex = is_complex(args[1]);
      const bool& arg0_is_scalar = is_saclar(args[0]);
      const bool& arg1_is_scalar = is_saclar(args[1]);
      complex_type c;

      if (arg0_is_complex && arg1_is_complex) {
        const Complex* obj0 =
            node::ObjectWrap::Unwrap<Complex>(args[0]->ToObject());
        const Complex* obj1 =
            node::ObjectWrap::Unwrap<Complex>(args[1]->ToObject());
        c = std::pow(obj0->complex_, obj1->complex_);
      } else if (arg0_is_complex && arg1_is_scalar) {
        const Complex* obj0 =
            node::ObjectWrap::Unwrap<Complex>(args[0]->ToObject());
        const element_type& scalar1 = args[1]->NumberValue();
        c = std::pow(obj0->complex_, scalar1);
      } else if (arg0_is_scalar && arg1_is_complex) {
        const element_type& scalar0 = args[0]->NumberValue();
        const Complex* obj1 =
            node::ObjectWrap::Unwrap<Complex>(args[1]->ToObject());
        c = std::pow(scalar0, obj1->complex_);
      } else if (arg0_is_scalar && arg1_is_scalar) {
        const element_type& scalar0 = args[0]->NumberValue();
        const element_type& scalar1 = args[1]->NumberValue();
        c = std::pow(scalar0, scalar1);
      }

      v8::Local<v8::Function> ctor = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {
          NanNew<v8::Number>(c.real())
        , NanNew<v8::Number>(c.imag())
      };

      v8::Local<v8::Object> new_complex = ctor->NewInstance(
          sizeof(argv) / sizeof(v8::Local<v8::Value>)
        , argv
      );

      NanReturnValue(new_complex);
    }

    NanReturnUndefined();
  }

  static NAN_METHOD(toString) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    std::ostringstream result;
    result << obj->complex_;

    NanReturnValue(NanNew(result.str().c_str()));

    NanReturnUndefined();
  }

  static NAN_GETTER(get_real) {
    NanScope();

    if (!NanGetInternalFieldPointer(args.This(), 0))
      NanReturnValue(args.This());

    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());

    NanReturnValue(NanNew(obj->complex_.real()));
  }

  static NAN_SETTER(set_real) {
    if (value->IsNumber()) {
      Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
      obj->complex_ = complex_type(
          value->NumberValue()
        , obj->complex_.imag()
      );
    }
  }

  static NAN_GETTER(get_imag) {
    NanScope();

    if (!NanGetInternalFieldPointer(args.This(), 0))
      NanReturnValue(args.This());

    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());

    NanReturnValue(NanNew(obj->complex_.imag()));
  }

  static NAN_SETTER(set_imag) {
    if (value->IsNumber()) {
      Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
      obj->complex_ = complex_type(
          obj->complex_.real()
        , value->NumberValue()
      );
    }
  }

 private:
  Complex(const element_type& real, const element_type& imag)
    : complex_(real, imag)
  {}
  ~Complex() {}

  static NAN_METHOD(New) {
    NanScope();

    if (args.Length() < 2) {
      NanThrowError("Tried creating complex without real and imag arguments");
      NanReturnUndefined();
    }

    if (args.IsConstructCall()) {
      const element_type& real = args[0]->NumberValue();
      const element_type& imag = args[1]->NumberValue();
      Complex* obj = new Complex(real, imag);
      obj->Wrap(args.This());
      NanReturnValue(args.This());
    } else {
      v8::Local<v8::Function> ctr = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {args[0], args[1]};
      NanReturnValue(
        ctr->NewInstance(
            sizeof(argv) / sizeof(v8::Local<v8::Value>)
          , argv
        )
      );
    }
  }

  static bool HasInstance(const v8::Handle<v8::Value>& value) {
    NanScope();
    v8::Local<v8::FunctionTemplate> tpl = NanNew(function_template);
    return tpl->HasInstance(value);
  }

 private:
  static v8::Persistent<v8::FunctionTemplate> function_template;
  static v8::Persistent<v8::Function> constructor;

 private:
  static bool is_complex(const v8::Handle<v8::Value>& arg) {
    return HasInstance(arg) ? true : false;
  }

  static bool is_saclar(const v8::Handle<v8::Value>& arg) {
    return arg->IsNumber() ? true : false;
  }

  static bool is_complex_or_saclar(const v8::Handle<v8::Value>& arg) {
    return HasInstance(arg) || arg->IsNumber()
      ? true : false;
  }

 private:
  complex_type complex_;
};

template<typename ValueType>
v8::Persistent<v8::FunctionTemplate> Complex<ValueType>::function_template;

template<typename ValueType>
v8::Persistent<v8::Function> Complex<ValueType>::constructor;

}  // namespace EigenJS

#undef EIGENJS_COMPLEX_CLASS_METHOD

#endif  // EIGENJS_COMPLEX_HPP
<commit_msg>src: added class method 'Complex.asin()'<commit_after>//
// EigenJS.cpp
// ~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot com)
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#ifndef EIGENJS_COMPLEX_HPP
#define EIGENJS_COMPLEX_HPP

#include <node.h>
#include <v8.h>

#include <nan.h>

#include <complex>
#include <sstream>

#define EIGENJS_COMPLEX_CLASS_METHOD( NAME )                                  \
  static NAN_METHOD( NAME ) {                                                 \
    NanScope();                                                               \
                                                                              \
    if ( args.Length() == 1 && HasInstance(args[0]) ) {                       \
      const Complex* obj =                                                    \
          node::ObjectWrap::Unwrap<Complex>( args[0]->ToObject() );           \
                                                                              \
      const complex_type& NAME = std::NAME( obj->complex_ );                  \
      const element_type& real = NAME.real();                                 \
      const element_type& imag = NAME.imag();                                 \
                                                                              \
      v8::Local<v8::Function> ctor = NanNew( constructor );                   \
      v8::Local<v8::Value> argv[] = {                                         \
          NanNew<v8::Number>( real )                                          \
        , NanNew<v8::Number>( imag )                                          \
      };                                                                      \
                                                                              \
      v8::Local<v8::Object> new_complex = ctor->NewInstance(                  \
          sizeof( argv ) / sizeof( v8::Local<v8::Value> )                     \
        , argv                                                                \
      );                                                                      \
                                                                              \
      NanReturnValue( new_complex );                                          \
    }                                                                         \
                                                                              \
    NanReturnUndefined();                                                     \
  }                                                                           \
/**/

namespace EigenJS {

template <typename ValueType>
class Complex : public node::ObjectWrap {
  typedef ValueType element_type;
  typedef std::complex<element_type> complex_type;

 public:
  static void Init(v8::Handle<v8::Object> exports) {
    NanScope();

    v8::Local<v8::FunctionTemplate> tpl = NanNew<v8::FunctionTemplate>(New);
    tpl->SetClassName(NanNew("Complex"));
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    NODE_SET_PROTOTYPE_METHOD(tpl, "abs", abs);
    NODE_SET_PROTOTYPE_METHOD(tpl, "arg", arg);
    NODE_SET_PROTOTYPE_METHOD(tpl, "norm", norm);
    NODE_SET_PROTOTYPE_METHOD(tpl, "conj", conj);

    NODE_SET_METHOD(tpl, "polar", polar);
    NODE_SET_METHOD(tpl, "proj", proj);

    NODE_SET_METHOD(tpl, "cos", cos);
    NODE_SET_METHOD(tpl, "cosh", cosh);
    NODE_SET_METHOD(tpl, "exp", exp);
    NODE_SET_METHOD(tpl, "log", log);
    NODE_SET_METHOD(tpl, "log10", log10);
    NODE_SET_METHOD(tpl, "pow", pow);
    NODE_SET_METHOD(tpl, "sin", sin);
    NODE_SET_METHOD(tpl, "sinh", sinh);
    NODE_SET_METHOD(tpl, "sqrt", sqrt);
    NODE_SET_METHOD(tpl, "tan", tan);
    NODE_SET_METHOD(tpl, "tanh", tanh);
    NODE_SET_METHOD(tpl, "acos", acos);
    NODE_SET_METHOD(tpl, "acosh", acosh);
    NODE_SET_METHOD(tpl, "asin", asin);

    NODE_SET_PROTOTYPE_METHOD(tpl, "toString", toString);

    v8::Local<v8::ObjectTemplate> proto = tpl->PrototypeTemplate();
    proto->SetAccessor(NanNew("real"), get_real, set_real);
    proto->SetAccessor(NanNew("imag"), get_imag, set_imag);

    NanAssignPersistent(constructor, tpl->GetFunction());
    exports->Set(NanNew("Complex"), tpl->GetFunction());

    NanAssignPersistent(function_template, tpl);
  }

  static NAN_METHOD(abs) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::abs(obj->complex_)));
  }

  static NAN_METHOD(arg) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::arg(obj->complex_)));
  }

  static NAN_METHOD(norm) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::norm(obj->complex_)));
  }

  static NAN_METHOD(conj) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    const complex_type& c = std::conj(obj->complex_);
    const element_type& real = c.real();
    const element_type& imag = c.imag();
    NanScope();

    v8::Local<v8::Function> ctor = NanNew(constructor);
    v8::Local<v8::Value> argv[] = {
        NanNew<v8::Number>(real)
      , NanNew<v8::Number>(imag)
    };

    v8::Local<v8::Object> new_complex = ctor->NewInstance(
        sizeof(argv) / sizeof(v8::Local<v8::Value>)
      , argv
    );

    NanReturnValue(new_complex);
  }

  static NAN_METHOD(polar) {
    NanScope();

    if (args.Length() == 2 &&
        args[0]->IsNumber() &&
        args[1]->IsNumber()) {
      const element_type& rho = args[0]->NumberValue();
      const element_type& theta = args[1]->NumberValue();

      v8::Local<v8::Function> ctor = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {
          NanNew<v8::Number>(rho)
        , NanNew<v8::Number>(theta)
      };

      v8::Local<v8::Object> new_complex = ctor->NewInstance(
          sizeof(argv) / sizeof(v8::Local<v8::Value>)
        , argv
      );

      NanReturnValue(new_complex);
    }

    NanReturnUndefined();
  }

  EIGENJS_COMPLEX_CLASS_METHOD(proj)
  EIGENJS_COMPLEX_CLASS_METHOD(cos)
  EIGENJS_COMPLEX_CLASS_METHOD(cosh)
  EIGENJS_COMPLEX_CLASS_METHOD(exp)
  EIGENJS_COMPLEX_CLASS_METHOD(log)
  EIGENJS_COMPLEX_CLASS_METHOD(log10)
  EIGENJS_COMPLEX_CLASS_METHOD(sin)
  EIGENJS_COMPLEX_CLASS_METHOD(sinh)
  EIGENJS_COMPLEX_CLASS_METHOD(sqrt)
  EIGENJS_COMPLEX_CLASS_METHOD(tan)
  EIGENJS_COMPLEX_CLASS_METHOD(tanh)
  EIGENJS_COMPLEX_CLASS_METHOD(acos)
  EIGENJS_COMPLEX_CLASS_METHOD(acosh)
  EIGENJS_COMPLEX_CLASS_METHOD(asin)

  static NAN_METHOD(pow) {
    NanScope();

    if (args.Length() == 2 &&
        is_complex_or_saclar(args[0]) &&
        is_complex_or_saclar(args[1])) {
      const bool& arg0_is_complex = is_complex(args[0]);
      const bool& arg1_is_complex = is_complex(args[1]);
      const bool& arg0_is_scalar = is_saclar(args[0]);
      const bool& arg1_is_scalar = is_saclar(args[1]);
      complex_type c;

      if (arg0_is_complex && arg1_is_complex) {
        const Complex* obj0 =
            node::ObjectWrap::Unwrap<Complex>(args[0]->ToObject());
        const Complex* obj1 =
            node::ObjectWrap::Unwrap<Complex>(args[1]->ToObject());
        c = std::pow(obj0->complex_, obj1->complex_);
      } else if (arg0_is_complex && arg1_is_scalar) {
        const Complex* obj0 =
            node::ObjectWrap::Unwrap<Complex>(args[0]->ToObject());
        const element_type& scalar1 = args[1]->NumberValue();
        c = std::pow(obj0->complex_, scalar1);
      } else if (arg0_is_scalar && arg1_is_complex) {
        const element_type& scalar0 = args[0]->NumberValue();
        const Complex* obj1 =
            node::ObjectWrap::Unwrap<Complex>(args[1]->ToObject());
        c = std::pow(scalar0, obj1->complex_);
      } else if (arg0_is_scalar && arg1_is_scalar) {
        const element_type& scalar0 = args[0]->NumberValue();
        const element_type& scalar1 = args[1]->NumberValue();
        c = std::pow(scalar0, scalar1);
      }

      v8::Local<v8::Function> ctor = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {
          NanNew<v8::Number>(c.real())
        , NanNew<v8::Number>(c.imag())
      };

      v8::Local<v8::Object> new_complex = ctor->NewInstance(
          sizeof(argv) / sizeof(v8::Local<v8::Value>)
        , argv
      );

      NanReturnValue(new_complex);
    }

    NanReturnUndefined();
  }

  static NAN_METHOD(toString) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    std::ostringstream result;
    result << obj->complex_;

    NanReturnValue(NanNew(result.str().c_str()));

    NanReturnUndefined();
  }

  static NAN_GETTER(get_real) {
    NanScope();

    if (!NanGetInternalFieldPointer(args.This(), 0))
      NanReturnValue(args.This());

    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());

    NanReturnValue(NanNew(obj->complex_.real()));
  }

  static NAN_SETTER(set_real) {
    if (value->IsNumber()) {
      Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
      obj->complex_ = complex_type(
          value->NumberValue()
        , obj->complex_.imag()
      );
    }
  }

  static NAN_GETTER(get_imag) {
    NanScope();

    if (!NanGetInternalFieldPointer(args.This(), 0))
      NanReturnValue(args.This());

    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());

    NanReturnValue(NanNew(obj->complex_.imag()));
  }

  static NAN_SETTER(set_imag) {
    if (value->IsNumber()) {
      Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
      obj->complex_ = complex_type(
          obj->complex_.real()
        , value->NumberValue()
      );
    }
  }

 private:
  Complex(const element_type& real, const element_type& imag)
    : complex_(real, imag)
  {}
  ~Complex() {}

  static NAN_METHOD(New) {
    NanScope();

    if (args.Length() < 2) {
      NanThrowError("Tried creating complex without real and imag arguments");
      NanReturnUndefined();
    }

    if (args.IsConstructCall()) {
      const element_type& real = args[0]->NumberValue();
      const element_type& imag = args[1]->NumberValue();
      Complex* obj = new Complex(real, imag);
      obj->Wrap(args.This());
      NanReturnValue(args.This());
    } else {
      v8::Local<v8::Function> ctr = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {args[0], args[1]};
      NanReturnValue(
        ctr->NewInstance(
            sizeof(argv) / sizeof(v8::Local<v8::Value>)
          , argv
        )
      );
    }
  }

  static bool HasInstance(const v8::Handle<v8::Value>& value) {
    NanScope();
    v8::Local<v8::FunctionTemplate> tpl = NanNew(function_template);
    return tpl->HasInstance(value);
  }

 private:
  static v8::Persistent<v8::FunctionTemplate> function_template;
  static v8::Persistent<v8::Function> constructor;

 private:
  static bool is_complex(const v8::Handle<v8::Value>& arg) {
    return HasInstance(arg) ? true : false;
  }

  static bool is_saclar(const v8::Handle<v8::Value>& arg) {
    return arg->IsNumber() ? true : false;
  }

  static bool is_complex_or_saclar(const v8::Handle<v8::Value>& arg) {
    return HasInstance(arg) || arg->IsNumber()
      ? true : false;
  }

 private:
  complex_type complex_;
};

template<typename ValueType>
v8::Persistent<v8::FunctionTemplate> Complex<ValueType>::function_template;

template<typename ValueType>
v8::Persistent<v8::Function> Complex<ValueType>::constructor;

}  // namespace EigenJS

#undef EIGENJS_COMPLEX_CLASS_METHOD

#endif  // EIGENJS_COMPLEX_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017-2019 CS Systemes d'Information (CS SI)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef otbMultiImageFileWriter_hxx
#define otbMultiImageFileWriter_hxx

#include "otbMultiImageFileWriter.h"
#include "otbImageIOFactory.h"
#include "otbMacro.h"

namespace otb
{

template <class TImage>
MultiImageFileWriter::Sink<TImage>::Sink(typename TImage::ConstPointer inputImage, const std::string& fileName)
  : SinkBase(dynamic_cast<const ImageBaseType*>(inputImage.GetPointer())), m_Writer(otb::ImageFileWriter<TImage>::New()), m_ImageIO(NULL)
{
  m_Writer->SetFileName(fileName);
  m_Writer->SetInput(inputImage);
}

template <class TImage>
MultiImageFileWriter::Sink<TImage>::Sink(typename otb::ImageFileWriter<TImage>::Pointer writer)
  : SinkBase(dynamic_cast<const ImageBaseType*>(writer->GetInput())), m_Writer(writer), m_ImageIO(NULL)
{
}

template <class TImage>
bool MultiImageFileWriter::Sink<TImage>::CanStreamWrite() const
{
  if (m_ImageIO.IsNull())
    return false;
  return m_ImageIO->CanStreamWrite();
}

template <class TImage>
void MultiImageFileWriter::Sink<TImage>::WriteImageInformation()
{
  m_Writer->UpdateOutputInformation();
  m_ImageIO = m_Writer->GetImageIO();
}

template <class TImage>
void MultiImageFileWriter::Sink<TImage>::Write(const RegionType& streamRegion)
{
  // Write the image stream
  itk::ImageIORegion ioRegion(TImage::ImageDimension);
  for (unsigned int i = 0; i < TImage::ImageDimension; ++i)
  {
    ioRegion.SetSize(i, streamRegion.GetSize(i));
    ioRegion.SetIndex(i, streamRegion.GetIndex(i));
  }
  m_ImageIO->SetIORegion(ioRegion);
  m_Writer->UpdateOutputData(nullptr);
}

template <class TImage>
itk::ImageRegion<2>
MultiImageFileWriter::Sink<TImage>::GetRegionToWrite() const
{
  auto fnameHelper = m_Writer->GetFilenameHelper();
  if (fnameHelper->BoxIsSet())
  {
    std::vector<unsigned int> boxVector;
    Utils::ConvertStringToVector(fnameHelper->GetBox(), boxVector, "ExtendedFileName:box", ":");

    if (boxVector.size() != 4)
    {
      itk::ImageFileWriterException e(__FILE__, __LINE__);
      std::ostringstream            msg;
      msg << "Invalid box option " << fnameHelper->GetBox() << ". The box should contains four elements: startx:starty:sizex:sizey";
      e.SetDescription(msg.str());
      e.SetLocation(ITK_LOCATION);
      throw e;
    }

    typename itk::ImageRegion<2>::IndexType start {boxVector[0], boxVector[1]};
    typename itk::ImageRegion<2>::SizeType size {boxVector[2], boxVector[3]};
    itk::ImageRegion<2> regionToWrite {start , size};
    regionToWrite.Crop(m_InputImage->GetLargestPossibleRegion());
    return regionToWrite;
  }
  else
  {
    return m_InputImage->GetLargestPossibleRegion();
  }
}

template <class TWriter>
void MultiImageFileWriter::AddInputWriter(typename TWriter::Pointer writer)
{
  Sink<typename TWriter::InputImageType>* sink = new Sink<typename TWriter::InputImageType>(writer);
  m_SinkList.push_back(SinkBase::Pointer(sink));
  unsigned int size = m_SinkList.size();
  this->SetNthInput(size - 1, const_cast<itk::DataObject*>(dynamic_cast<const itk::DataObject*>(writer->GetInput())));
      /** Parse streaming modes */

  auto filenameHelper = writer->GetFilenameHelper();
  if (filenameHelper->StreamingTypeIsSet())
  {
    otbLogMacro(
        Warning,
        << "Streaming configuration through extended filename is used. Any previous streaming configuration (ram value, streaming mode ...) will be ignored.");

    std::string type = filenameHelper->GetStreamingType();

    std::string sizemode = "auto";

    if (filenameHelper->StreamingSizeModeIsSet())
    {
      sizemode = filenameHelper->GetStreamingSizeMode();
    }

    unsigned int sizevalue = 0;
    // Save the DefaultRAM value for later
    unsigned int oldDefaultRAM = m_StreamingManager->GetDefaultRAM();
    if (sizemode == "auto")
    {
      sizevalue = oldDefaultRAM;
    }

    if (filenameHelper->StreamingSizeValueIsSet())
    {
      sizevalue = static_cast<unsigned int>(filenameHelper->GetStreamingSizeValue());
    }

    if (type == "auto")
    {
      if (sizemode != "auto")
      {
        otbLogMacro(Warning, << "In auto streaming type, the sizemode option will be ignored.");
      }
      if (sizevalue == 0)
      {
        otbLogMacro(Warning, << "sizemode is auto but sizevalue is 0. Value will be fetched from the OTB_MAX_RAM_HINT environment variable if set, or else use "
                                "the default value");
      }
      this->SetAutomaticAdaptativeStreaming(sizevalue);
    }
    else if (type == "tiled")
    {
      if (sizemode == "auto")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "sizemode is auto but sizevalue is 0. Value will be fetched from the OTB_MAX_RAM_HINT environment variable if set, or else "
                                  "use the default value");
        }
        this->SetAutomaticTiledStreaming(sizevalue);
      }
      else if (sizemode == "nbsplits")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "Streaming sizemode is set to nbsplits but sizevalue is 0. This will result in undefined behaviour. Please consider setting "
                                  "the sizevalue by using &streaming:sizevalue=x.");
        }
        this->SetNumberOfDivisionsTiledStreaming(sizevalue);
      }
      else if (sizemode == "height")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "Streaming sizemode is set to height but sizevalue is 0. This will result in undefined behaviour. Please consider setting "
                                  "the sizevalue by using &streaming:sizevalue=x.");
        }

        this->SetTileDimensionTiledStreaming(sizevalue);
      }
    }
    else if (type == "stripped")
    {
      if (sizemode == "auto")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(
              Warning, << "sizemode is auto but sizevalue is 0. Value will be fetched from configuration file if any, or from cmake configuration otherwise.");
        }

        this->SetAutomaticStrippedStreaming(sizevalue);
      }
      else if (sizemode == "nbsplits")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "Streaming sizemode is set to nbsplits but sizevalue is 0. This will result in undefined behaviour. Please consider setting "
                                  "the sizevalue by using &streaming:sizevalue=x.");
        }
        this->SetNumberOfDivisionsStrippedStreaming(sizevalue);
      }
      else if (sizemode == "height")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "Streaming sizemode is set to height but sizevalue is 0. This will result in undefined behaviour. Please consider setting "
                                  "the sizevalue by using &streaming:sizevalue=x.");
        }
        this->SetNumberOfLinesStrippedStreaming(sizevalue);
      }
    }
    else if (type == "none")
    {
      if (sizemode != "" || sizevalue != 0)
      {
        otbLogMacro(Warning, << "Streaming is explicitly disabled, sizemode and sizevalue will be ignored.");
      }
      this->SetNumberOfDivisionsTiledStreaming(0);
    }
    m_StreamingManager->SetDefaultRAM(oldDefaultRAM);
  }
  else
  {
    if (filenameHelper->StreamingSizeValueIsSet() || filenameHelper->StreamingSizeModeIsSet())
    {
      otbLogMacro(Warning, << "No streaming type is set, streaming sizemode and sizevalue will be ignored.");
    }
  }
}

template <class TImage>
void MultiImageFileWriter::AddInputImage(const TImage* inputPtr, const std::string& fileName)
{
  Sink<TImage>* sink = new Sink<TImage>(inputPtr, fileName);
  m_SinkList.push_back(SinkBase::Pointer(sink));
  unsigned int size = m_SinkList.size();
  this->SetNthInput(size - 1, const_cast<itk::DataObject*>(dynamic_cast<const itk::DataObject*>(inputPtr)));
}

} // end of namespace otb

#endif // otbMultiImageFileWriter_hxx
<commit_msg>WRG: fix clang warning<commit_after>/*
 * Copyright (C) 2017-2019 CS Systemes d'Information (CS SI)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef otbMultiImageFileWriter_hxx
#define otbMultiImageFileWriter_hxx

#include "otbMultiImageFileWriter.h"
#include "otbImageIOFactory.h"
#include "otbMacro.h"

namespace otb
{

template <class TImage>
MultiImageFileWriter::Sink<TImage>::Sink(typename TImage::ConstPointer inputImage, const std::string& fileName)
  : SinkBase(dynamic_cast<const ImageBaseType*>(inputImage.GetPointer())), m_Writer(otb::ImageFileWriter<TImage>::New()), m_ImageIO(NULL)
{
  m_Writer->SetFileName(fileName);
  m_Writer->SetInput(inputImage);
}

template <class TImage>
MultiImageFileWriter::Sink<TImage>::Sink(typename otb::ImageFileWriter<TImage>::Pointer writer)
  : SinkBase(dynamic_cast<const ImageBaseType*>(writer->GetInput())), m_Writer(writer), m_ImageIO(NULL)
{
}

template <class TImage>
bool MultiImageFileWriter::Sink<TImage>::CanStreamWrite() const
{
  if (m_ImageIO.IsNull())
    return false;
  return m_ImageIO->CanStreamWrite();
}

template <class TImage>
void MultiImageFileWriter::Sink<TImage>::WriteImageInformation()
{
  m_Writer->UpdateOutputInformation();
  m_ImageIO = m_Writer->GetImageIO();
}

template <class TImage>
void MultiImageFileWriter::Sink<TImage>::Write(const RegionType& streamRegion)
{
  // Write the image stream
  itk::ImageIORegion ioRegion(TImage::ImageDimension);
  for (unsigned int i = 0; i < TImage::ImageDimension; ++i)
  {
    ioRegion.SetSize(i, streamRegion.GetSize(i));
    ioRegion.SetIndex(i, streamRegion.GetIndex(i));
  }
  m_ImageIO->SetIORegion(ioRegion);
  m_Writer->UpdateOutputData(nullptr);
}

template <class TImage>
itk::ImageRegion<2>
MultiImageFileWriter::Sink<TImage>::GetRegionToWrite() const
{
  auto fnameHelper = m_Writer->GetFilenameHelper();
  if (fnameHelper->BoxIsSet())
  {
    std::vector<unsigned int> boxVector;
    Utils::ConvertStringToVector(fnameHelper->GetBox(), boxVector, "ExtendedFileName:box", ":");

    if (boxVector.size() != 4)
    {
      itk::ImageFileWriterException e(__FILE__, __LINE__);
      std::ostringstream            msg;
      msg << "Invalid box option " << fnameHelper->GetBox() << ". The box should contains four elements: startx:starty:sizex:sizey";
      e.SetDescription(msg.str());
      e.SetLocation(ITK_LOCATION);
      throw e;
    }

    typename itk::ImageRegion<2>::IndexType start {{boxVector[0], boxVector[1]}};
    typename itk::ImageRegion<2>::SizeType size {{boxVector[2], boxVector[3]}};
    itk::ImageRegion<2> regionToWrite {start , size};
    regionToWrite.Crop(m_InputImage->GetLargestPossibleRegion());
    return regionToWrite;
  }
  else
  {
    return m_InputImage->GetLargestPossibleRegion();
  }
}

template <class TWriter>
void MultiImageFileWriter::AddInputWriter(typename TWriter::Pointer writer)
{
  Sink<typename TWriter::InputImageType>* sink = new Sink<typename TWriter::InputImageType>(writer);
  m_SinkList.push_back(SinkBase::Pointer(sink));
  unsigned int size = m_SinkList.size();
  this->SetNthInput(size - 1, const_cast<itk::DataObject*>(dynamic_cast<const itk::DataObject*>(writer->GetInput())));
      /** Parse streaming modes */

  auto filenameHelper = writer->GetFilenameHelper();
  if (filenameHelper->StreamingTypeIsSet())
  {
    otbLogMacro(
        Warning,
        << "Streaming configuration through extended filename is used. Any previous streaming configuration (ram value, streaming mode ...) will be ignored.");

    std::string type = filenameHelper->GetStreamingType();

    std::string sizemode = "auto";

    if (filenameHelper->StreamingSizeModeIsSet())
    {
      sizemode = filenameHelper->GetStreamingSizeMode();
    }

    unsigned int sizevalue = 0;
    // Save the DefaultRAM value for later
    unsigned int oldDefaultRAM = m_StreamingManager->GetDefaultRAM();
    if (sizemode == "auto")
    {
      sizevalue = oldDefaultRAM;
    }

    if (filenameHelper->StreamingSizeValueIsSet())
    {
      sizevalue = static_cast<unsigned int>(filenameHelper->GetStreamingSizeValue());
    }

    if (type == "auto")
    {
      if (sizemode != "auto")
      {
        otbLogMacro(Warning, << "In auto streaming type, the sizemode option will be ignored.");
      }
      if (sizevalue == 0)
      {
        otbLogMacro(Warning, << "sizemode is auto but sizevalue is 0. Value will be fetched from the OTB_MAX_RAM_HINT environment variable if set, or else use "
                                "the default value");
      }
      this->SetAutomaticAdaptativeStreaming(sizevalue);
    }
    else if (type == "tiled")
    {
      if (sizemode == "auto")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "sizemode is auto but sizevalue is 0. Value will be fetched from the OTB_MAX_RAM_HINT environment variable if set, or else "
                                  "use the default value");
        }
        this->SetAutomaticTiledStreaming(sizevalue);
      }
      else if (sizemode == "nbsplits")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "Streaming sizemode is set to nbsplits but sizevalue is 0. This will result in undefined behaviour. Please consider setting "
                                  "the sizevalue by using &streaming:sizevalue=x.");
        }
        this->SetNumberOfDivisionsTiledStreaming(sizevalue);
      }
      else if (sizemode == "height")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "Streaming sizemode is set to height but sizevalue is 0. This will result in undefined behaviour. Please consider setting "
                                  "the sizevalue by using &streaming:sizevalue=x.");
        }

        this->SetTileDimensionTiledStreaming(sizevalue);
      }
    }
    else if (type == "stripped")
    {
      if (sizemode == "auto")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(
              Warning, << "sizemode is auto but sizevalue is 0. Value will be fetched from configuration file if any, or from cmake configuration otherwise.");
        }

        this->SetAutomaticStrippedStreaming(sizevalue);
      }
      else if (sizemode == "nbsplits")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "Streaming sizemode is set to nbsplits but sizevalue is 0. This will result in undefined behaviour. Please consider setting "
                                  "the sizevalue by using &streaming:sizevalue=x.");
        }
        this->SetNumberOfDivisionsStrippedStreaming(sizevalue);
      }
      else if (sizemode == "height")
      {
        if (sizevalue == 0)
        {
          otbLogMacro(Warning, << "Streaming sizemode is set to height but sizevalue is 0. This will result in undefined behaviour. Please consider setting "
                                  "the sizevalue by using &streaming:sizevalue=x.");
        }
        this->SetNumberOfLinesStrippedStreaming(sizevalue);
      }
    }
    else if (type == "none")
    {
      if (sizemode != "" || sizevalue != 0)
      {
        otbLogMacro(Warning, << "Streaming is explicitly disabled, sizemode and sizevalue will be ignored.");
      }
      this->SetNumberOfDivisionsTiledStreaming(0);
    }
    m_StreamingManager->SetDefaultRAM(oldDefaultRAM);
  }
  else
  {
    if (filenameHelper->StreamingSizeValueIsSet() || filenameHelper->StreamingSizeModeIsSet())
    {
      otbLogMacro(Warning, << "No streaming type is set, streaming sizemode and sizevalue will be ignored.");
    }
  }
}

template <class TImage>
void MultiImageFileWriter::AddInputImage(const TImage* inputPtr, const std::string& fileName)
{
  Sink<TImage>* sink = new Sink<TImage>(inputPtr, fileName);
  m_SinkList.push_back(SinkBase::Pointer(sink));
  unsigned int size = m_SinkList.size();
  this->SetNthInput(size - 1, const_cast<itk::DataObject*>(dynamic_cast<const itk::DataObject*>(inputPtr)));
}

} // end of namespace otb

#endif // otbMultiImageFileWriter_hxx
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MasterPageDescriptor.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 19:19:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "MasterPageDescriptor.hxx"

#include "DocumentHelper.hxx"
#include "sdpage.hxx"

#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif

namespace sd { namespace toolpanel { namespace controls {

//===== MasterPageDescriptor ==================================================

MasterPageDescriptor::MasterPageDescriptor (
    MasterPageContainer::Origin eOrigin,
    const sal_Int32 nTemplateIndex,
    const String& rsURL,
    const String& rsPageName,
    const String& rsStyleName,
    const ::boost::shared_ptr<PageObjectProvider>& rpPageObjectProvider,
    const ::boost::shared_ptr<PreviewProvider>& rpPreviewProvider)
    : maToken(MasterPageContainer::NIL_TOKEN),
      meOrigin(eOrigin),
      msURL(INetURLObject(rsURL).GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS)),
      msPageName(rsPageName),
      msStyleName(rsStyleName),
      mpMasterPage(NULL),
      mpSlide(NULL),
      maSmallPreview(),
      maLargePreview(),
      mpPreviewProvider(rpPreviewProvider),
      mpPageObjectProvider(rpPageObjectProvider),
      mnTemplateIndex(nTemplateIndex),
      meURLClassification(URLCLASS_UNDETERMINED),
      mnUseCount(0)
{
}

MasterPageDescriptor::MasterPageDescriptor (const MasterPageDescriptor& rDescriptor)
    : maToken(rDescriptor.maToken),
      meOrigin(rDescriptor.meOrigin),
      msURL(rDescriptor.msURL),
      msPageName(rDescriptor.msPageName),
      msStyleName(rDescriptor.msStyleName),
      mpMasterPage(rDescriptor.mpMasterPage),
      mpSlide(rDescriptor.mpSlide),
      maSmallPreview(rDescriptor.maSmallPreview),
      maLargePreview(rDescriptor.maLargePreview),
      mpPreviewProvider(rDescriptor.mpPreviewProvider),
      mpPageObjectProvider(rDescriptor.mpPageObjectProvider),
      mnTemplateIndex(rDescriptor.mnTemplateIndex),
      meURLClassification(rDescriptor.meURLClassification),
      mnUseCount(rDescriptor.mnUseCount)
{
}

MasterPageDescriptor::~MasterPageDescriptor (void)
{
}

void MasterPageDescriptor::SetToken (MasterPageContainer::Token aToken)
{
    maToken = aToken;
}

Image MasterPageDescriptor::GetPreview (MasterPageContainer::PreviewSize eSize)
{
    if (eSize == MasterPageContainer::SMALL)
        return maSmallPreview;
    else
        return maLargePreview;
}

::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> >
    MasterPageDescriptor::Update (
        const MasterPageDescriptor& rDescriptor)
{
    bool bDataChanged (false);
    bool bIndexChanged (false);
    bool bPreviewChanged (false);

    if (meOrigin==MasterPageContainer::UNKNOWN
        && rDescriptor.meOrigin!=MasterPageContainer::UNKNOWN)
    {
        meOrigin = rDescriptor.meOrigin;
        bIndexChanged = true;
    }

    if (msURL.getLength()==0 && rDescriptor.msURL.getLength()!=0)
    {
        msURL = rDescriptor.msURL;
        bDataChanged = true;
    }

    if (msPageName.getLength()==0 && rDescriptor.msPageName.getLength()!=0)
    {
        msPageName = rDescriptor.msPageName;
        bDataChanged = true;
    }

    if (msStyleName.getLength()==0 && rDescriptor.msStyleName.getLength()!=0)
    {
        msStyleName = rDescriptor.msStyleName;
        bDataChanged = true;
    }

    if (mpPageObjectProvider.get()==NULL && rDescriptor.mpPageObjectProvider.get()!=NULL)
    {
        mpPageObjectProvider = rDescriptor.mpPageObjectProvider;
        bDataChanged = true;
    }

     if (mpPreviewProvider.get()==NULL && rDescriptor.mpPreviewProvider.get()!=NULL)
     {
         mpPreviewProvider = rDescriptor.mpPreviewProvider;
         bPreviewChanged = true;
     }

     if (mnTemplateIndex<0 && rDescriptor.mnTemplateIndex>=0)
     {
         mnTemplateIndex = rDescriptor.mnTemplateIndex;
         bIndexChanged = true;
     }

     // Prepare the list of event types that will be returned.
     ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pResult;
     if (bDataChanged || bIndexChanged || bPreviewChanged)
     {
         pResult.reset(new std::vector<MasterPageContainerChangeEvent::EventType>());
         if (bDataChanged)
             pResult->push_back(MasterPageContainerChangeEvent::DATA_CHANGED);
         if (bIndexChanged)
             pResult->push_back(MasterPageContainerChangeEvent::INDEX_CHANGED);
         if (bPreviewChanged)
             pResult->push_back(MasterPageContainerChangeEvent::PREVIEW_CHANGED);
     }

     return pResult;
}

bool MasterPageDescriptor::UpdatePageObject (
    sal_Int32 nCostThreshold,
    SdDrawDocument* pDocument)
{
    bool bModified (false);

    // Update the page object when that is not yet known.
    if (mpMasterPage == NULL
        && mpPageObjectProvider.get()!=NULL
        && (nCostThreshold<0 || mpPageObjectProvider->GetCostIndex()<=nCostThreshold))
    {
        // Note that pDocument may be NULL.

        SdPage* pPage = (*mpPageObjectProvider)(pDocument);
        if (meOrigin == MasterPageContainer::MASTERPAGE)
        {
            mpMasterPage = pPage;
        }
        else
        {
            // Master pages from templates are copied into the local document.
            if (pDocument != NULL)
                mpMasterPage = DocumentHelper::CopyMasterPageToLocalDocument(*pDocument,pPage);
            mpSlide = DocumentHelper::GetSlideForMasterPage(mpMasterPage);
        }

        if (mpMasterPage != NULL)
        {
            // Update page name and style name.
            if (msPageName.getLength() == 0)
                msPageName = mpMasterPage->GetName();
            msStyleName = mpMasterPage->GetName();

            // Delete an existing substitution. The next request for a preview
            // will create the real one.
            maSmallPreview = Image();
            maLargePreview = Image();
            mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider());
        }
        else
        {
            DBG_ASSERT(false, "UpdatePageObject: master page is NULL");
        }

        bModified = true;
    }

    return bModified;
}

bool MasterPageDescriptor::UpdatePreview (
    sal_Int32 nCostThreshold,
    const Size& rSmallSize,
    const Size& rLargeSize,
    ::sd::PreviewRenderer& rRenderer)
{
    bool bModified (false);

    // Update the preview when that is not yet known.
    if (maLargePreview.GetSizePixel().Width()==0
        && mpPreviewProvider.get()!=NULL
        && (nCostThreshold<0 || mpPreviewProvider->GetCostIndex()<=nCostThreshold))
    {
        SdPage* pPage = mpSlide;
        if (pPage == NULL)
        {
            pPage = mpMasterPage;
        }
        maLargePreview = (*mpPreviewProvider)(
            rLargeSize.Width(),
            pPage,
            rRenderer);
        if (maLargePreview.GetSizePixel().Width() > 0)
        {
            // Create the small preview by scaling the large one down.
            maSmallPreview = rRenderer.ScaleBitmap(
                maLargePreview.GetBitmapEx(),
                rSmallSize.Width());
            // The large preview may not have the desired width.  Scale it
            // accrodingly.
            if (maLargePreview.GetSizePixel().Width() != rLargeSize.Width())
                maLargePreview = rRenderer.ScaleBitmap(
                    maLargePreview.GetBitmapEx(),
                    rLargeSize.Width());
            bModified = true;
        }
    }

    return bModified;
}

MasterPageDescriptor::URLClassification MasterPageDescriptor::GetURLClassification (void)
{
    if (meURLClassification == URLCLASS_UNDETERMINED)
    {
        if (msURL.getLength() == 0)
            meURLClassification = URLCLASS_UNKNOWN;
        else if (msURL.indexOf(::rtl::OUString::createFromAscii("presnt"))>=0)
        {
            meURLClassification = URLCLASS_PRESENTATION;
        }
        else if (msURL.indexOf(::rtl::OUString::createFromAscii("layout"))>=0)
        {
            meURLClassification = URLCLASS_LAYOUT;
        }
        else if (msURL.indexOf(::rtl::OUString::createFromAscii("educate"))>=0)
        {
            meURLClassification = URLCLASS_OTHER;
        }
        else
        {
            meURLClassification = URLCLASS_USER;
        }
    }

    return meURLClassification;
}

//===== URLComparator =========================================================

MasterPageDescriptor::URLComparator::URLComparator (const ::rtl::OUString& sURL)
    : msURL(sURL)
{
}

bool MasterPageDescriptor::URLComparator::operator() (
    const SharedMasterPageDescriptor& rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
        return rDescriptor->msURL.equals(msURL);
}

//===== PageNameComparator ====================================================

MasterPageDescriptor::PageNameComparator::PageNameComparator (const ::rtl::OUString& sPageName)
    : msPageName(sPageName)
{
}

bool MasterPageDescriptor::PageNameComparator::operator() (
    const SharedMasterPageDescriptor& rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
        return rDescriptor->msPageName.equals(msPageName);
}

// ===== StyleNameComparator ==================================================

MasterPageDescriptor::StyleNameComparator::StyleNameComparator (const ::rtl::OUString& sStyleName)
    : msStyleName(sStyleName)
{
}

bool MasterPageDescriptor::StyleNameComparator::operator() (
    const SharedMasterPageDescriptor& rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
        return rDescriptor->msStyleName.equals(msStyleName);
}

//===== PageObjectComparator ==================================================

MasterPageDescriptor::PageObjectComparator::PageObjectComparator (const SdPage* pPageObject)
    : mpMasterPage(pPageObject)
{
}

bool MasterPageDescriptor::PageObjectComparator::operator() (
    const SharedMasterPageDescriptor& rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
        return rDescriptor->mpMasterPage==mpMasterPage;
}

//===== AllComparator =========================================================

MasterPageDescriptor::AllComparator::AllComparator(const SharedMasterPageDescriptor& rDescriptor)
    : mpDescriptor(rDescriptor)
{
}

bool MasterPageDescriptor::AllComparator::operator() (const SharedMasterPageDescriptor&rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
    {
        // Take URL, page name, style name, and page object into account
        // when comparing two descriptors.  When two descriptors are
        // identical in any of these values then their are thought of as
        // equivalent.  Only the Origin has to be the same in both
        // descriptors.
        return
            mpDescriptor->meOrigin == rDescriptor->meOrigin
            && (
                (mpDescriptor->msURL.getLength()>0
                    && mpDescriptor->msURL.equals(rDescriptor->msURL))
                || (mpDescriptor->msPageName.getLength()>0
                    && mpDescriptor->msPageName.equals(rDescriptor->msPageName))
                || (mpDescriptor->msStyleName.getLength()>0
                    && mpDescriptor->msStyleName.equals(rDescriptor->msStyleName))
                || (mpDescriptor->mpMasterPage!=NULL
                    && mpDescriptor->mpMasterPage==rDescriptor->mpMasterPage)
                || (mpDescriptor->mpPageObjectProvider.get()!=NULL
                    && rDescriptor->mpPageObjectProvider.get()!=NULL
                    && mpDescriptor->mpPageObjectProvider==rDescriptor->mpPageObjectProvider));
    }
}

} } } // end of namespace ::sd::toolpanel::controls
<commit_msg>INTEGRATION: CWS changefileheader (1.3.358); FILE MERGED 2008/04/01 15:36:08 thb 1.3.358.2: #i85898# Stripping all external header guards 2008/03/31 13:59:02 rt 1.3.358.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: MasterPageDescriptor.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "MasterPageDescriptor.hxx"

#include "DocumentHelper.hxx"
#include "sdpage.hxx"
#include <tools/urlobj.hxx>

namespace sd { namespace toolpanel { namespace controls {

//===== MasterPageDescriptor ==================================================

MasterPageDescriptor::MasterPageDescriptor (
    MasterPageContainer::Origin eOrigin,
    const sal_Int32 nTemplateIndex,
    const String& rsURL,
    const String& rsPageName,
    const String& rsStyleName,
    const ::boost::shared_ptr<PageObjectProvider>& rpPageObjectProvider,
    const ::boost::shared_ptr<PreviewProvider>& rpPreviewProvider)
    : maToken(MasterPageContainer::NIL_TOKEN),
      meOrigin(eOrigin),
      msURL(INetURLObject(rsURL).GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS)),
      msPageName(rsPageName),
      msStyleName(rsStyleName),
      mpMasterPage(NULL),
      mpSlide(NULL),
      maSmallPreview(),
      maLargePreview(),
      mpPreviewProvider(rpPreviewProvider),
      mpPageObjectProvider(rpPageObjectProvider),
      mnTemplateIndex(nTemplateIndex),
      meURLClassification(URLCLASS_UNDETERMINED),
      mnUseCount(0)
{
}

MasterPageDescriptor::MasterPageDescriptor (const MasterPageDescriptor& rDescriptor)
    : maToken(rDescriptor.maToken),
      meOrigin(rDescriptor.meOrigin),
      msURL(rDescriptor.msURL),
      msPageName(rDescriptor.msPageName),
      msStyleName(rDescriptor.msStyleName),
      mpMasterPage(rDescriptor.mpMasterPage),
      mpSlide(rDescriptor.mpSlide),
      maSmallPreview(rDescriptor.maSmallPreview),
      maLargePreview(rDescriptor.maLargePreview),
      mpPreviewProvider(rDescriptor.mpPreviewProvider),
      mpPageObjectProvider(rDescriptor.mpPageObjectProvider),
      mnTemplateIndex(rDescriptor.mnTemplateIndex),
      meURLClassification(rDescriptor.meURLClassification),
      mnUseCount(rDescriptor.mnUseCount)
{
}

MasterPageDescriptor::~MasterPageDescriptor (void)
{
}

void MasterPageDescriptor::SetToken (MasterPageContainer::Token aToken)
{
    maToken = aToken;
}

Image MasterPageDescriptor::GetPreview (MasterPageContainer::PreviewSize eSize)
{
    if (eSize == MasterPageContainer::SMALL)
        return maSmallPreview;
    else
        return maLargePreview;
}

::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> >
    MasterPageDescriptor::Update (
        const MasterPageDescriptor& rDescriptor)
{
    bool bDataChanged (false);
    bool bIndexChanged (false);
    bool bPreviewChanged (false);

    if (meOrigin==MasterPageContainer::UNKNOWN
        && rDescriptor.meOrigin!=MasterPageContainer::UNKNOWN)
    {
        meOrigin = rDescriptor.meOrigin;
        bIndexChanged = true;
    }

    if (msURL.getLength()==0 && rDescriptor.msURL.getLength()!=0)
    {
        msURL = rDescriptor.msURL;
        bDataChanged = true;
    }

    if (msPageName.getLength()==0 && rDescriptor.msPageName.getLength()!=0)
    {
        msPageName = rDescriptor.msPageName;
        bDataChanged = true;
    }

    if (msStyleName.getLength()==0 && rDescriptor.msStyleName.getLength()!=0)
    {
        msStyleName = rDescriptor.msStyleName;
        bDataChanged = true;
    }

    if (mpPageObjectProvider.get()==NULL && rDescriptor.mpPageObjectProvider.get()!=NULL)
    {
        mpPageObjectProvider = rDescriptor.mpPageObjectProvider;
        bDataChanged = true;
    }

     if (mpPreviewProvider.get()==NULL && rDescriptor.mpPreviewProvider.get()!=NULL)
     {
         mpPreviewProvider = rDescriptor.mpPreviewProvider;
         bPreviewChanged = true;
     }

     if (mnTemplateIndex<0 && rDescriptor.mnTemplateIndex>=0)
     {
         mnTemplateIndex = rDescriptor.mnTemplateIndex;
         bIndexChanged = true;
     }

     // Prepare the list of event types that will be returned.
     ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pResult;
     if (bDataChanged || bIndexChanged || bPreviewChanged)
     {
         pResult.reset(new std::vector<MasterPageContainerChangeEvent::EventType>());
         if (bDataChanged)
             pResult->push_back(MasterPageContainerChangeEvent::DATA_CHANGED);
         if (bIndexChanged)
             pResult->push_back(MasterPageContainerChangeEvent::INDEX_CHANGED);
         if (bPreviewChanged)
             pResult->push_back(MasterPageContainerChangeEvent::PREVIEW_CHANGED);
     }

     return pResult;
}

bool MasterPageDescriptor::UpdatePageObject (
    sal_Int32 nCostThreshold,
    SdDrawDocument* pDocument)
{
    bool bModified (false);

    // Update the page object when that is not yet known.
    if (mpMasterPage == NULL
        && mpPageObjectProvider.get()!=NULL
        && (nCostThreshold<0 || mpPageObjectProvider->GetCostIndex()<=nCostThreshold))
    {
        // Note that pDocument may be NULL.

        SdPage* pPage = (*mpPageObjectProvider)(pDocument);
        if (meOrigin == MasterPageContainer::MASTERPAGE)
        {
            mpMasterPage = pPage;
        }
        else
        {
            // Master pages from templates are copied into the local document.
            if (pDocument != NULL)
                mpMasterPage = DocumentHelper::CopyMasterPageToLocalDocument(*pDocument,pPage);
            mpSlide = DocumentHelper::GetSlideForMasterPage(mpMasterPage);
        }

        if (mpMasterPage != NULL)
        {
            // Update page name and style name.
            if (msPageName.getLength() == 0)
                msPageName = mpMasterPage->GetName();
            msStyleName = mpMasterPage->GetName();

            // Delete an existing substitution. The next request for a preview
            // will create the real one.
            maSmallPreview = Image();
            maLargePreview = Image();
            mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider());
        }
        else
        {
            DBG_ASSERT(false, "UpdatePageObject: master page is NULL");
        }

        bModified = true;
    }

    return bModified;
}

bool MasterPageDescriptor::UpdatePreview (
    sal_Int32 nCostThreshold,
    const Size& rSmallSize,
    const Size& rLargeSize,
    ::sd::PreviewRenderer& rRenderer)
{
    bool bModified (false);

    // Update the preview when that is not yet known.
    if (maLargePreview.GetSizePixel().Width()==0
        && mpPreviewProvider.get()!=NULL
        && (nCostThreshold<0 || mpPreviewProvider->GetCostIndex()<=nCostThreshold))
    {
        SdPage* pPage = mpSlide;
        if (pPage == NULL)
        {
            pPage = mpMasterPage;
        }
        maLargePreview = (*mpPreviewProvider)(
            rLargeSize.Width(),
            pPage,
            rRenderer);
        if (maLargePreview.GetSizePixel().Width() > 0)
        {
            // Create the small preview by scaling the large one down.
            maSmallPreview = rRenderer.ScaleBitmap(
                maLargePreview.GetBitmapEx(),
                rSmallSize.Width());
            // The large preview may not have the desired width.  Scale it
            // accrodingly.
            if (maLargePreview.GetSizePixel().Width() != rLargeSize.Width())
                maLargePreview = rRenderer.ScaleBitmap(
                    maLargePreview.GetBitmapEx(),
                    rLargeSize.Width());
            bModified = true;
        }
    }

    return bModified;
}

MasterPageDescriptor::URLClassification MasterPageDescriptor::GetURLClassification (void)
{
    if (meURLClassification == URLCLASS_UNDETERMINED)
    {
        if (msURL.getLength() == 0)
            meURLClassification = URLCLASS_UNKNOWN;
        else if (msURL.indexOf(::rtl::OUString::createFromAscii("presnt"))>=0)
        {
            meURLClassification = URLCLASS_PRESENTATION;
        }
        else if (msURL.indexOf(::rtl::OUString::createFromAscii("layout"))>=0)
        {
            meURLClassification = URLCLASS_LAYOUT;
        }
        else if (msURL.indexOf(::rtl::OUString::createFromAscii("educate"))>=0)
        {
            meURLClassification = URLCLASS_OTHER;
        }
        else
        {
            meURLClassification = URLCLASS_USER;
        }
    }

    return meURLClassification;
}

//===== URLComparator =========================================================

MasterPageDescriptor::URLComparator::URLComparator (const ::rtl::OUString& sURL)
    : msURL(sURL)
{
}

bool MasterPageDescriptor::URLComparator::operator() (
    const SharedMasterPageDescriptor& rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
        return rDescriptor->msURL.equals(msURL);
}

//===== PageNameComparator ====================================================

MasterPageDescriptor::PageNameComparator::PageNameComparator (const ::rtl::OUString& sPageName)
    : msPageName(sPageName)
{
}

bool MasterPageDescriptor::PageNameComparator::operator() (
    const SharedMasterPageDescriptor& rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
        return rDescriptor->msPageName.equals(msPageName);
}

// ===== StyleNameComparator ==================================================

MasterPageDescriptor::StyleNameComparator::StyleNameComparator (const ::rtl::OUString& sStyleName)
    : msStyleName(sStyleName)
{
}

bool MasterPageDescriptor::StyleNameComparator::operator() (
    const SharedMasterPageDescriptor& rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
        return rDescriptor->msStyleName.equals(msStyleName);
}

//===== PageObjectComparator ==================================================

MasterPageDescriptor::PageObjectComparator::PageObjectComparator (const SdPage* pPageObject)
    : mpMasterPage(pPageObject)
{
}

bool MasterPageDescriptor::PageObjectComparator::operator() (
    const SharedMasterPageDescriptor& rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
        return rDescriptor->mpMasterPage==mpMasterPage;
}

//===== AllComparator =========================================================

MasterPageDescriptor::AllComparator::AllComparator(const SharedMasterPageDescriptor& rDescriptor)
    : mpDescriptor(rDescriptor)
{
}

bool MasterPageDescriptor::AllComparator::operator() (const SharedMasterPageDescriptor&rDescriptor)
{
    if (rDescriptor.get() == NULL)
        return false;
    else
    {
        // Take URL, page name, style name, and page object into account
        // when comparing two descriptors.  When two descriptors are
        // identical in any of these values then their are thought of as
        // equivalent.  Only the Origin has to be the same in both
        // descriptors.
        return
            mpDescriptor->meOrigin == rDescriptor->meOrigin
            && (
                (mpDescriptor->msURL.getLength()>0
                    && mpDescriptor->msURL.equals(rDescriptor->msURL))
                || (mpDescriptor->msPageName.getLength()>0
                    && mpDescriptor->msPageName.equals(rDescriptor->msPageName))
                || (mpDescriptor->msStyleName.getLength()>0
                    && mpDescriptor->msStyleName.equals(rDescriptor->msStyleName))
                || (mpDescriptor->mpMasterPage!=NULL
                    && mpDescriptor->mpMasterPage==rDescriptor->mpMasterPage)
                || (mpDescriptor->mpPageObjectProvider.get()!=NULL
                    && rDescriptor->mpPageObjectProvider.get()!=NULL
                    && mpDescriptor->mpPageObjectProvider==rDescriptor->mpPageObjectProvider));
    }
}

} } } // end of namespace ::sd::toolpanel::controls
<|endoftext|>