<commit_before>/*
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */

// CLASS  HEADER
#include "bidirectional-support-impl.h"

// INTERNAL INCLUDES
#include <singleton-service-impl.h>

// EXTERNAL INCLUDES
#include <memory.h>
#include <fribidi/fribidi.h>

namespace Dali
{

namespace TextAbstraction
{

namespace Internal
{

namespace
{
  typedef unsigned char BidiDirection;

  // Internal charcter's direction.
  const BidiDirection LEFT_TO_RIGHT = 0u;
  const BidiDirection NEUTRAL = 1u;
  const BidiDirection RIGHT_TO_LEFT = 2u;

  /**
   * @param[in] paragraphDirection The FriBiDi paragraph's direction.
   *
   * @return Whether the paragraph is right to left.
   */
  bool GetBidiParagraphDirection( FriBidiParType paragraphDirection )
  {
    switch( paragraphDirection )
    {
      case FRIBIDI_PAR_RTL:  // Right-To-Left paragraph.
      case FRIBIDI_PAR_WRTL: // Weak Right To Left paragraph.
      {
        return true;
      }
      case FRIBIDI_PAR_LTR:  // Left-To-Right paragraph.
      case FRIBIDI_PAR_ON:   // DirectiOn-Neutral paragraph.
      case FRIBIDI_PAR_WLTR: // Weak Left To Right paragraph.
      {
        return false;
      }
    }

    return false;
  }

  BidiDirection GetBidiCharacterDirection( FriBidiCharType characterDirection )
  {
    switch( characterDirection )
    {
      case FRIBIDI_TYPE_LTR: // Left-To-Right letter.
      case FRIBIDI_TYPE_EN:  // European Numeral.
      case FRIBIDI_TYPE_AN:  // Arabic Numeral.
      case FRIBIDI_TYPE_ES:  // European number Separator.
      case FRIBIDI_TYPE_ET:  // European number Terminator.
      {
        return LEFT_TO_RIGHT;
      }
      case FRIBIDI_TYPE_RTL: // Right-To-Left letter.
      case FRIBIDI_TYPE_AL:  // Arabic Letter.
      {
        return RIGHT_TO_LEFT;
      }
    }

    return NEUTRAL;
  }
}

struct BidirectionalSupport::Plugin
{
  /**
   * Stores bidirectional info per paragraph.
   */
  struct BidirectionalInfo
  {
    FriBidiCharType* characterTypes;      ///< The type of each character (right, left, neutral, ...)
    FriBidiLevel*    embeddedLevels;      ///< Embedded levels.
    FriBidiParType   paragraphDirection;  ///< The paragraph's direction.
  };

  Plugin()
  : mParagraphBidirectionalInfo(),
    mFreeIndices()
  {}

  ~Plugin()
  {
    // free all resources.
    for( Vector<BidirectionalInfo*>::Iterator it = mParagraphBidirectionalInfo.Begin(),
           endIt = mParagraphBidirectionalInfo.End();
         it != endIt;
         ++it )
    {
      BidirectionalInfo* info = *it;

      free( info->embeddedLevels );
      free( info->characterTypes );
      delete info;
    }
  }

  BidiInfoIndex CreateInfo( const Character* const paragraph,
                            Length numberOfCharacters )
  {
    // Reserve memory for the paragraph's bidirectional info.
    BidirectionalInfo* bidirectionalInfo = new BidirectionalInfo();

    bidirectionalInfo->characterTypes = reinterpret_cast<FriBidiCharType*>( malloc( numberOfCharacters * sizeof( FriBidiCharType ) ) );
    bidirectionalInfo->embeddedLevels = reinterpret_cast<FriBidiLevel*>( malloc( numberOfCharacters * sizeof( FriBidiLevel ) ) );

    // Retrieve the type of each character..
    fribidi_get_bidi_types( paragraph, numberOfCharacters, bidirectionalInfo->characterTypes );

    // Retrieve the paragraph's direction.
    bidirectionalInfo->paragraphDirection = fribidi_get_par_direction( bidirectionalInfo->characterTypes, numberOfCharacters );

    // Retrieve the embedding levels.
    fribidi_get_par_embedding_levels( bidirectionalInfo->characterTypes, numberOfCharacters, &bidirectionalInfo->paragraphDirection, bidirectionalInfo->embeddedLevels );

    // Store the bidirectional info and return the index.
    BidiInfoIndex index = 0u;
    if( 0u != mFreeIndices.Count() )
    {
      Vector<BidiInfoIndex>::Iterator it = mFreeIndices.End() - 1u;

      index = *it;

      mFreeIndices.Remove( it );

      *( mParagraphBidirectionalInfo.Begin() + index ) = bidirectionalInfo;
    }
    else
    {
      index = static_cast<BidiInfoIndex>( mParagraphBidirectionalInfo.Count() );

      mParagraphBidirectionalInfo.PushBack( bidirectionalInfo );
    }

    return index;
  }

  void DestroyInfo( BidiInfoIndex bidiInfoIndex )
  {
    if( bidiInfoIndex >= mParagraphBidirectionalInfo.Count() )
    {
      return;
    }

    // Retrieve the paragraph's bidirectional info.
    Vector<BidirectionalInfo*>::Iterator it = mParagraphBidirectionalInfo.Begin() + bidiInfoIndex;
    BidirectionalInfo* bidirectionalInfo = *it;

    if( NULL != bidirectionalInfo )
    {
      // Free resources and destroy the container.
      free( bidirectionalInfo->embeddedLevels );
      free( bidirectionalInfo->characterTypes );
      delete bidirectionalInfo;

      *it = NULL;
    }

    // Add the index to the free indices vector.
    mFreeIndices.PushBack( bidiInfoIndex );
  }

  void Reorder( BidiInfoIndex bidiInfoIndex,
                CharacterIndex firstCharacterIndex,
                Length numberOfCharacters,
                CharacterIndex* visualToLogicalMap )
  {
    const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;

    // Retrieve the paragraph's bidirectional info.
    const BidirectionalInfo* const bidirectionalInfo = *( mParagraphBidirectionalInfo.Begin() + bidiInfoIndex );

    // Initialize the visual to logical mapping table to the identity. Otherwise fribidi_reorder_line fails to retrieve a valid mapping table.
    for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
    {
      visualToLogicalMap[ index ] = index;
    }

    // Copy embedded levels as fribidi_reorder_line() may change them.
    const uint32_t embeddedLevelsSize = numberOfCharacters * sizeof( FriBidiLevel );
    FriBidiLevel* embeddedLevels = reinterpret_cast<FriBidiLevel*>( malloc( embeddedLevelsSize ) );
    memcpy( embeddedLevels, bidirectionalInfo->embeddedLevels + firstCharacterIndex,  embeddedLevelsSize );

    // Reorder the line.
    fribidi_reorder_line( flags,
                          bidirectionalInfo->characterTypes + firstCharacterIndex,
                          numberOfCharacters,
                          0u,
                          bidirectionalInfo->paragraphDirection,
                          embeddedLevels,
                          NULL,
                          reinterpret_cast<FriBidiStrIndex*>( visualToLogicalMap ) );

    // Free resources.
    free( embeddedLevels );
  }

  bool GetMirroredText( Character* text,
                        Length numberOfCharacters ) const
  {
    bool updated = false;

    for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
    {
      // Get a reference to the character inside the text.
      Character& character = *( text + index );

      // Retrieve the mirrored character.
      FriBidiChar mirroredCharacter = character;
      const bool mirrored = fribidi_get_mirror_char( character, &mirroredCharacter );
      updated = updated || mirrored;

      // Update the character inside the text.
      character = mirroredCharacter;
    }

    return updated;
  }

  bool GetParagraphDirection( BidiInfoIndex bidiInfoIndex ) const
  {
    // Retrieve the paragraph's bidirectional info.
    const BidirectionalInfo* const bidirectionalInfo = *( mParagraphBidirectionalInfo.Begin() + bidiInfoIndex );

    return GetBidiParagraphDirection( bidirectionalInfo->paragraphDirection );
  }

  void GetCharactersDirection( BidiInfoIndex bidiInfoIndex,
                               CharacterDirection* directions,
                               Length numberOfCharacters )
  {
    const BidirectionalInfo* const bidirectionalInfo = *( mParagraphBidirectionalInfo.Begin() + bidiInfoIndex );

    const CharacterDirection paragraphDirection = GetBidiParagraphDirection( bidirectionalInfo->paragraphDirection );
    CharacterDirection previousDirection = paragraphDirection;

    for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
    {
      CharacterDirection& characterDirection = *( directions + index );
      characterDirection = false;

      // Get the bidi direction.
      const BidiDirection bidiDirection = GetBidiCharacterDirection( *( bidirectionalInfo->characterTypes + index ) );

      if( RIGHT_TO_LEFT == bidiDirection )
      {
        characterDirection = true;
      }
      else if( NEUTRAL == bidiDirection )
      {
        // For neutral characters it check's the next and previous directions.
        // If they are equals set that direction. If they are not, sets the paragraph's direction.
        // If there is no next, sets the paragraph's direction.

        CharacterDirection nextDirection = paragraphDirection;
        const Length nextIndex = index + 1u;
        if( nextIndex < numberOfCharacters )
        {
          const BidiDirection nextBidiDirection = GetBidiCharacterDirection( *( bidirectionalInfo->characterTypes + nextIndex ) );

          nextDirection = RIGHT_TO_LEFT == nextBidiDirection;
        }

        characterDirection = previousDirection == nextDirection ? previousDirection : paragraphDirection;
      }
    }
  }

  Vector<BidirectionalInfo*> mParagraphBidirectionalInfo; ///< Stores the bidirectional info per paragraph.
  Vector<BidiInfoIndex>      mFreeIndices;                ///< Stores indices of free positions in the bidirectional info vector.
};

BidirectionalSupport::BidirectionalSupport()
: mPlugin( NULL )
{
}

BidirectionalSupport::~BidirectionalSupport()
{
  delete mPlugin;
}

TextAbstraction::BidirectionalSupport BidirectionalSupport::Get()
{
  TextAbstraction::BidirectionalSupport bidirectionalSupportHandle;

  SingletonService service( SingletonService::Get() );
  if( service )
  {
    // Check whether the singleton is already created
    BaseHandle handle = service.GetSingleton( typeid( TextAbstraction::BidirectionalSupport ) );
    if(handle)
    {
      // If so, downcast the handle
      BidirectionalSupport* impl = dynamic_cast< Internal::BidirectionalSupport* >( handle.GetObjectPtr() );
      bidirectionalSupportHandle = TextAbstraction::BidirectionalSupport( impl );
    }
    else // create and register the object
    {
      bidirectionalSupportHandle = TextAbstraction::BidirectionalSupport( new BidirectionalSupport );
      service.Register( typeid( bidirectionalSupportHandle ), bidirectionalSupportHandle );
    }
  }

  return bidirectionalSupportHandle;
}

BidiInfoIndex BidirectionalSupport::CreateInfo( const Character* const paragraph,
                                                Length numberOfCharacters )
{
  CreatePlugin();

  return mPlugin->CreateInfo( paragraph,
                              numberOfCharacters );
}

void BidirectionalSupport::DestroyInfo( BidiInfoIndex bidiInfoIndex )
{
  CreatePlugin();

  mPlugin->DestroyInfo( bidiInfoIndex );
}

void BidirectionalSupport::Reorder( BidiInfoIndex bidiInfoIndex,
                                    CharacterIndex firstCharacterIndex,
                                    Length numberOfCharacters,
                                    CharacterIndex* visualToLogicalMap )
{
  CreatePlugin();

  mPlugin->Reorder( bidiInfoIndex,
                    firstCharacterIndex,
                    numberOfCharacters,
                    visualToLogicalMap );
}

bool BidirectionalSupport::GetMirroredText( Character* text,
                                            Length numberOfCharacters )
{
  CreatePlugin();

  return mPlugin->GetMirroredText( text, numberOfCharacters );
}

bool BidirectionalSupport::GetParagraphDirection( BidiInfoIndex bidiInfoIndex ) const
{
  if( !mPlugin )
  {
    return false;
  }

  return mPlugin->GetParagraphDirection( bidiInfoIndex );
}

void BidirectionalSupport::GetCharactersDirection( BidiInfoIndex bidiInfoIndex,
                                                   CharacterDirection* directions,
                                                   Length numberOfCharacters )
{
  CreatePlugin();

  mPlugin->GetCharactersDirection( bidiInfoIndex,
                                   directions,
                                   numberOfCharacters );
}

void BidirectionalSupport::CreatePlugin()
{
  if( !mPlugin )
  {
    mPlugin = new Plugin();
  }
}

} // namespace Internal

} // namespace TextAbstraction

} // namespace Dali
<commit_msg>Fix for GetCharactersDirection().   Was not giving the correct direction for neutral characters.<commit_after>/*
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */

// CLASS  HEADER
#include "bidirectional-support-impl.h"

// INTERNAL INCLUDES
#include <singleton-service-impl.h>

// EXTERNAL INCLUDES
#include <memory.h>
#include <fribidi/fribidi.h>

namespace Dali
{

namespace TextAbstraction
{

namespace Internal
{

namespace
{
  typedef unsigned char BidiDirection;

  // Internal charcter's direction.
  const BidiDirection LEFT_TO_RIGHT = 0u;
  const BidiDirection NEUTRAL = 1u;
  const BidiDirection RIGHT_TO_LEFT = 2u;

  /**
   * @param[in] paragraphDirection The FriBiDi paragraph's direction.
   *
   * @return Whether the paragraph is right to left.
   */
  bool GetBidiParagraphDirection( FriBidiParType paragraphDirection )
  {
    switch( paragraphDirection )
    {
      case FRIBIDI_PAR_RTL:  // Right-To-Left paragraph.
      case FRIBIDI_PAR_WRTL: // Weak Right To Left paragraph.
      {
        return true;
      }
      case FRIBIDI_PAR_LTR:  // Left-To-Right paragraph.
      case FRIBIDI_PAR_ON:   // DirectiOn-Neutral paragraph.
      case FRIBIDI_PAR_WLTR: // Weak Left To Right paragraph.
      {
        return false;
      }
    }

    return false;
  }

  BidiDirection GetBidiCharacterDirection( FriBidiCharType characterDirection )
  {
    switch( characterDirection )
    {
      case FRIBIDI_TYPE_LTR: // Left-To-Right letter.
      case FRIBIDI_TYPE_EN:  // European Numeral.
      case FRIBIDI_TYPE_AN:  // Arabic Numeral.
      case FRIBIDI_TYPE_ES:  // European number Separator.
      case FRIBIDI_TYPE_ET:  // European number Terminator.
      {
        return LEFT_TO_RIGHT;
      }
      case FRIBIDI_TYPE_RTL: // Right-To-Left letter.
      case FRIBIDI_TYPE_AL:  // Arabic Letter.
      {
        return RIGHT_TO_LEFT;
      }
    }

    return NEUTRAL;
  }
}

struct BidirectionalSupport::Plugin
{
  /**
   * Stores bidirectional info per paragraph.
   */
  struct BidirectionalInfo
  {
    FriBidiCharType* characterTypes;      ///< The type of each character (right, left, neutral, ...)
    FriBidiLevel*    embeddedLevels;      ///< Embedded levels.
    FriBidiParType   paragraphDirection;  ///< The paragraph's direction.
  };

  Plugin()
  : mParagraphBidirectionalInfo(),
    mFreeIndices()
  {}

  ~Plugin()
  {
    // free all resources.
    for( Vector<BidirectionalInfo*>::Iterator it = mParagraphBidirectionalInfo.Begin(),
           endIt = mParagraphBidirectionalInfo.End();
         it != endIt;
         ++it )
    {
      BidirectionalInfo* info = *it;

      free( info->embeddedLevels );
      free( info->characterTypes );
      delete info;
    }
  }

  BidiInfoIndex CreateInfo( const Character* const paragraph,
                            Length numberOfCharacters )
  {
    // Reserve memory for the paragraph's bidirectional info.
    BidirectionalInfo* bidirectionalInfo = new BidirectionalInfo();

    bidirectionalInfo->characterTypes = reinterpret_cast<FriBidiCharType*>( malloc( numberOfCharacters * sizeof( FriBidiCharType ) ) );
    bidirectionalInfo->embeddedLevels = reinterpret_cast<FriBidiLevel*>( malloc( numberOfCharacters * sizeof( FriBidiLevel ) ) );

    // Retrieve the type of each character..
    fribidi_get_bidi_types( paragraph, numberOfCharacters, bidirectionalInfo->characterTypes );

    // Retrieve the paragraph's direction.
    bidirectionalInfo->paragraphDirection = fribidi_get_par_direction( bidirectionalInfo->characterTypes, numberOfCharacters );

    // Retrieve the embedding levels.
    fribidi_get_par_embedding_levels( bidirectionalInfo->characterTypes, numberOfCharacters, &bidirectionalInfo->paragraphDirection, bidirectionalInfo->embeddedLevels );

    // Store the bidirectional info and return the index.
    BidiInfoIndex index = 0u;
    if( 0u != mFreeIndices.Count() )
    {
      Vector<BidiInfoIndex>::Iterator it = mFreeIndices.End() - 1u;

      index = *it;

      mFreeIndices.Remove( it );

      *( mParagraphBidirectionalInfo.Begin() + index ) = bidirectionalInfo;
    }
    else
    {
      index = static_cast<BidiInfoIndex>( mParagraphBidirectionalInfo.Count() );

      mParagraphBidirectionalInfo.PushBack( bidirectionalInfo );
    }

    return index;
  }

  void DestroyInfo( BidiInfoIndex bidiInfoIndex )
  {
    if( bidiInfoIndex >= mParagraphBidirectionalInfo.Count() )
    {
      return;
    }

    // Retrieve the paragraph's bidirectional info.
    Vector<BidirectionalInfo*>::Iterator it = mParagraphBidirectionalInfo.Begin() + bidiInfoIndex;
    BidirectionalInfo* bidirectionalInfo = *it;

    if( NULL != bidirectionalInfo )
    {
      // Free resources and destroy the container.
      free( bidirectionalInfo->embeddedLevels );
      free( bidirectionalInfo->characterTypes );
      delete bidirectionalInfo;

      *it = NULL;
    }

    // Add the index to the free indices vector.
    mFreeIndices.PushBack( bidiInfoIndex );
  }

  void Reorder( BidiInfoIndex bidiInfoIndex,
                CharacterIndex firstCharacterIndex,
                Length numberOfCharacters,
                CharacterIndex* visualToLogicalMap )
  {
    const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;

    // Retrieve the paragraph's bidirectional info.
    const BidirectionalInfo* const bidirectionalInfo = *( mParagraphBidirectionalInfo.Begin() + bidiInfoIndex );

    // Initialize the visual to logical mapping table to the identity. Otherwise fribidi_reorder_line fails to retrieve a valid mapping table.
    for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
    {
      visualToLogicalMap[ index ] = index;
    }

    // Copy embedded levels as fribidi_reorder_line() may change them.
    const uint32_t embeddedLevelsSize = numberOfCharacters * sizeof( FriBidiLevel );
    FriBidiLevel* embeddedLevels = reinterpret_cast<FriBidiLevel*>( malloc( embeddedLevelsSize ) );
    memcpy( embeddedLevels, bidirectionalInfo->embeddedLevels + firstCharacterIndex,  embeddedLevelsSize );

    // Reorder the line.
    fribidi_reorder_line( flags,
                          bidirectionalInfo->characterTypes + firstCharacterIndex,
                          numberOfCharacters,
                          0u,
                          bidirectionalInfo->paragraphDirection,
                          embeddedLevels,
                          NULL,
                          reinterpret_cast<FriBidiStrIndex*>( visualToLogicalMap ) );

    // Free resources.
    free( embeddedLevels );
  }

  bool GetMirroredText( Character* text,
                        Length numberOfCharacters ) const
  {
    bool updated = false;

    for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
    {
      // Get a reference to the character inside the text.
      Character& character = *( text + index );

      // Retrieve the mirrored character.
      FriBidiChar mirroredCharacter = character;
      const bool mirrored = fribidi_get_mirror_char( character, &mirroredCharacter );
      updated = updated || mirrored;

      // Update the character inside the text.
      character = mirroredCharacter;
    }

    return updated;
  }

  bool GetParagraphDirection( BidiInfoIndex bidiInfoIndex ) const
  {
    // Retrieve the paragraph's bidirectional info.
    const BidirectionalInfo* const bidirectionalInfo = *( mParagraphBidirectionalInfo.Begin() + bidiInfoIndex );

    return GetBidiParagraphDirection( bidirectionalInfo->paragraphDirection );
  }

  void GetCharactersDirection( BidiInfoIndex bidiInfoIndex,
                               CharacterDirection* directions,
                               Length numberOfCharacters )
  {
    const BidirectionalInfo* const bidirectionalInfo = *( mParagraphBidirectionalInfo.Begin() + bidiInfoIndex );

    const CharacterDirection paragraphDirection = GetBidiParagraphDirection( bidirectionalInfo->paragraphDirection );
    CharacterDirection previousDirection = paragraphDirection;

    for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
    {
      CharacterDirection& characterDirection = *( directions + index );
      characterDirection = false;

      // Get the bidi direction.
      const BidiDirection bidiDirection = GetBidiCharacterDirection( *( bidirectionalInfo->characterTypes + index ) );

      if( RIGHT_TO_LEFT == bidiDirection )
      {
        characterDirection = true;
      }
      else if( NEUTRAL == bidiDirection )
      {
        // For neutral characters it check's the next and previous directions.
        // If they are equals set that direction. If they are not, sets the paragraph's direction.
        // If there is no next, sets the paragraph's direction.

        CharacterDirection nextDirection = paragraphDirection;
        const Length nextIndex = index + 1u;
        if( nextIndex < numberOfCharacters )
        {
          const BidiDirection nextBidiDirection = GetBidiCharacterDirection( *( bidirectionalInfo->characterTypes + nextIndex ) );

          nextDirection = RIGHT_TO_LEFT == nextBidiDirection;
        }

        characterDirection = previousDirection == nextDirection ? previousDirection : paragraphDirection;
      }

      previousDirection = characterDirection;
    }
  }

  Vector<BidirectionalInfo*> mParagraphBidirectionalInfo; ///< Stores the bidirectional info per paragraph.
  Vector<BidiInfoIndex>      mFreeIndices;                ///< Stores indices of free positions in the bidirectional info vector.
};

BidirectionalSupport::BidirectionalSupport()
: mPlugin( NULL )
{
}

BidirectionalSupport::~BidirectionalSupport()
{
  delete mPlugin;
}

TextAbstraction::BidirectionalSupport BidirectionalSupport::Get()
{
  TextAbstraction::BidirectionalSupport bidirectionalSupportHandle;

  SingletonService service( SingletonService::Get() );
  if( service )
  {
    // Check whether the singleton is already created
    BaseHandle handle = service.GetSingleton( typeid( TextAbstraction::BidirectionalSupport ) );
    if(handle)
    {
      // If so, downcast the handle
      BidirectionalSupport* impl = dynamic_cast< Internal::BidirectionalSupport* >( handle.GetObjectPtr() );
      bidirectionalSupportHandle = TextAbstraction::BidirectionalSupport( impl );
    }
    else // create and register the object
    {
      bidirectionalSupportHandle = TextAbstraction::BidirectionalSupport( new BidirectionalSupport );
      service.Register( typeid( bidirectionalSupportHandle ), bidirectionalSupportHandle );
    }
  }

  return bidirectionalSupportHandle;
}

BidiInfoIndex BidirectionalSupport::CreateInfo( const Character* const paragraph,
                                                Length numberOfCharacters )
{
  CreatePlugin();

  return mPlugin->CreateInfo( paragraph,
                              numberOfCharacters );
}

void BidirectionalSupport::DestroyInfo( BidiInfoIndex bidiInfoIndex )
{
  CreatePlugin();

  mPlugin->DestroyInfo( bidiInfoIndex );
}

void BidirectionalSupport::Reorder( BidiInfoIndex bidiInfoIndex,
                                    CharacterIndex firstCharacterIndex,
                                    Length numberOfCharacters,
                                    CharacterIndex* visualToLogicalMap )
{
  CreatePlugin();

  mPlugin->Reorder( bidiInfoIndex,
                    firstCharacterIndex,
                    numberOfCharacters,
                    visualToLogicalMap );
}

bool BidirectionalSupport::GetMirroredText( Character* text,
                                            Length numberOfCharacters )
{
  CreatePlugin();

  return mPlugin->GetMirroredText( text, numberOfCharacters );
}

bool BidirectionalSupport::GetParagraphDirection( BidiInfoIndex bidiInfoIndex ) const
{
  if( !mPlugin )
  {
    return false;
  }

  return mPlugin->GetParagraphDirection( bidiInfoIndex );
}

void BidirectionalSupport::GetCharactersDirection( BidiInfoIndex bidiInfoIndex,
                                                   CharacterDirection* directions,
                                                   Length numberOfCharacters )
{
  CreatePlugin();

  mPlugin->GetCharactersDirection( bidiInfoIndex,
                                   directions,
                                   numberOfCharacters );
}

void BidirectionalSupport::CreatePlugin()
{
  if( !mPlugin )
  {
    mPlugin = new Plugin();
  }
}

} // namespace Internal

} // namespace TextAbstraction

} // namespace Dali
<|endoftext|>


<commit_before>#include "androidoglcontextfactory.hpp"
#include "android_gl_utils.hpp"

#include "base/assert.hpp"
#include "base/logging.hpp"
#include "base/src_point.hpp"

#include <algorithm>

#include <EGL/egl.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>

#define EGL_OPENGL_ES3_BIT 0x00000040

namespace android
{
namespace
{
static EGLint * getConfigAttributesListRGB8(bool supportedES3)
{
  static EGLint attr_list[] = {
    EGL_RED_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    EGL_ALPHA_SIZE, 0,
    EGL_STENCIL_SIZE, 0,
    EGL_DEPTH_SIZE, 16,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
    EGL_NONE
  };
  static EGLint attr_list_es3[] = {
    EGL_RED_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    EGL_ALPHA_SIZE, 0,
    EGL_STENCIL_SIZE, 0,
    EGL_DEPTH_SIZE, 16,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
    EGL_NONE
  };
  return supportedES3 ? attr_list_es3 : attr_list;
}

int const kMaxConfigCount = 40;

static EGLint * getConfigAttributesListR5G6B5()
{
  // We do not support OpenGL ES3 for R5G6B5, because some Android devices
  // are not able to create OpenGL context in such mode.
  static EGLint attr_list[] = {
    EGL_RED_SIZE, 5,
    EGL_GREEN_SIZE, 6,
    EGL_BLUE_SIZE, 5,
    EGL_STENCIL_SIZE, 0,
    EGL_DEPTH_SIZE, 16,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
    EGL_NONE
  };
  return attr_list;
}

bool IsSupportedRGB8(EGLDisplay display, bool es3)
{
  EGLConfig configs[kMaxConfigCount];
  int count = 0;
  return eglChooseConfig(display, getConfigAttributesListRGB8(es3), configs,
                         kMaxConfigCount, &count) == EGL_TRUE;
}
}  // namespace

AndroidOGLContextFactory::AndroidOGLContextFactory(JNIEnv * env, jobject jsurface)
  : m_drawContext(NULL)
  , m_uploadContext(NULL)
  , m_windowSurface(EGL_NO_SURFACE)
  , m_pixelbufferSurface(EGL_NO_SURFACE)
  , m_config(NULL)
  , m_nativeWindow(NULL)
  , m_display(EGL_NO_DISPLAY)
  , m_surfaceWidth(0)
  , m_surfaceHeight(0)
  , m_windowSurfaceValid(false)
  , m_supportedES3(false)
{
  m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  if (m_display == EGL_NO_DISPLAY)
  {
    CHECK_EGL_CALL();
    return;
  }

  EGLint version[2] = {0};
  if (!eglInitialize(m_display, &version[0], &version[1]))
  {
    CHECK_EGL_CALL();
    return;
  }

  m_supportedES3 = gl3stubInit() && IsSupportedRGB8(m_display, true /* es3 */);

  SetSurface(env, jsurface);

  if (!createPixelbufferSurface())
  {
    CHECK_EGL(eglTerminate(m_display));
    return;
  }
}

AndroidOGLContextFactory::~AndroidOGLContextFactory()
{
  if (m_drawContext != nullptr)
  {
    delete m_drawContext;
    m_drawContext = nullptr;
  }

  if (m_uploadContext != nullptr)
  {
    delete m_uploadContext;
    m_uploadContext = nullptr;
  }

  ResetSurface();

  if (m_pixelbufferSurface != EGL_NO_SURFACE)
  {
    eglDestroySurface(m_display, m_pixelbufferSurface);
    CHECK_EGL_CALL();
    m_pixelbufferSurface = EGL_NO_SURFACE;
  }

  if (m_display != EGL_NO_DISPLAY)
  {
    eglTerminate(m_display);
    CHECK_EGL_CALL();
  }
}

void AndroidOGLContextFactory::SetSurface(JNIEnv * env, jobject jsurface)
{
  if (!jsurface)
    return;

  m_nativeWindow = ANativeWindow_fromSurface(env, jsurface);
  if (!m_nativeWindow)
  {
    LOG(LINFO, ("Can't get native window from Java surface"));
    return;
  }

  if (!createWindowSurface())
  {
    CHECK_EGL(eglTerminate(m_display));
    return;
  }

  if (!QuerySurfaceSize())
    return;

  if (m_drawContext != nullptr)
    m_drawContext->setSurface(m_windowSurface);

  m_windowSurfaceValid = true;
}

void AndroidOGLContextFactory::ResetSurface()
{
  if (m_drawContext != nullptr)
    m_drawContext->resetSurface();

  if (IsValid())
  {
    eglDestroySurface(m_display, m_windowSurface);
    CHECK_EGL_CALL();
    m_windowSurface = EGL_NO_SURFACE;

    ANativeWindow_release(m_nativeWindow);
    m_nativeWindow = NULL;

    m_windowSurfaceValid = false;
  }
}

bool AndroidOGLContextFactory::IsValid() const
{
  return m_windowSurfaceValid && m_pixelbufferSurface != EGL_NO_SURFACE;
}

int AndroidOGLContextFactory::GetWidth() const
{
  ASSERT(IsValid(), ());
  return m_surfaceWidth;
}

int AndroidOGLContextFactory::GetHeight() const
{
  ASSERT(IsValid(), ());
  return m_surfaceHeight;
}

void AndroidOGLContextFactory::UpdateSurfaceSize()
{
  ASSERT(IsValid(), ());
  QuerySurfaceSize();
}

bool AndroidOGLContextFactory::QuerySurfaceSize()
{
  EGLint queryResult;
  if (eglQuerySurface(m_display, m_windowSurface, EGL_WIDTH, &queryResult) == EGL_FALSE)
  {
    CHECK_EGL_CALL();
    return false;
  }

  m_surfaceWidth = static_cast<int>(queryResult);
  if (eglQuerySurface(m_display, m_windowSurface, EGL_HEIGHT, &queryResult) == EGL_FALSE)
  {
    CHECK_EGL_CALL();
    return false;
  }

  m_surfaceHeight = static_cast<int>(queryResult);
  return true;
}

dp::OGLContext * AndroidOGLContextFactory::getDrawContext()
{
  ASSERT(IsValid(), ());
  ASSERT(m_windowSurface != EGL_NO_SURFACE, ());
  if (m_drawContext == nullptr)
  {
    m_drawContext = new AndroidOGLContext(m_supportedES3, m_display, m_windowSurface,
                                          m_config, m_uploadContext);
  }
  return m_drawContext;
}

dp::OGLContext * AndroidOGLContextFactory::getResourcesUploadContext()
{
  ASSERT(IsValid(), ());
  ASSERT(m_pixelbufferSurface != EGL_NO_SURFACE, ());
  if (m_uploadContext == nullptr)
  {
    m_uploadContext = new AndroidOGLContext(m_supportedES3, m_display, m_pixelbufferSurface,
                                            m_config, m_drawContext);
  }
  return m_uploadContext;
}

bool AndroidOGLContextFactory::isDrawContextCreated() const
{
  return m_drawContext != nullptr;
}

bool AndroidOGLContextFactory::isUploadContextCreated() const
{
  return m_uploadContext != nullptr;
}

bool AndroidOGLContextFactory::createWindowSurface()
{
  EGLConfig configs[kMaxConfigCount];
  int count = 0;
  if (eglChooseConfig(m_display, getConfigAttributesListRGB8(m_supportedES3), configs,
                      kMaxConfigCount, &count) != EGL_TRUE)
  {
    ASSERT(!m_supportedES3, ());
    VERIFY(eglChooseConfig(m_display, getConfigAttributesListR5G6B5(), configs,
                                      kMaxConfigCount, &count) == EGL_TRUE, ());
    LOG(LDEBUG, ("Backbuffer format: R5G6B5"));
  }
  else
  {
    LOG(LDEBUG, ("Backbuffer format: RGB8"));
  }
  ASSERT(count > 0, ("Didn't find any configs."));

  std::sort(&configs[0], &configs[count], ConfigComparator(m_display));
  for (int i = 0; i < count; ++i)
  {
    EGLConfig currentConfig = configs[i];

    EGLint format;
    eglGetConfigAttrib(m_display, currentConfig, EGL_NATIVE_VISUAL_ID, &format);
    ANativeWindow_setBuffersGeometry(m_nativeWindow, 0, 0, format);

    EGLint surfaceAttributes[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
    m_windowSurface = eglCreateWindowSurface(m_display, currentConfig, m_nativeWindow, surfaceAttributes);
    if (m_windowSurface == EGL_NO_SURFACE)
      continue;
    else
      m_config = currentConfig;

    break;
  }

  if (m_windowSurface == EGL_NO_SURFACE)
  {
    CHECK_EGL_CALL();
    return false;
  }

  return true;
}

bool AndroidOGLContextFactory::createPixelbufferSurface()
{
  //ASSERT(m_config != NULL, ());

  const GLuint size = 1; // yes, 1 is the correct size, we dont really draw on it
  static EGLint surfaceConfig[] = {
      EGL_WIDTH, size,
      EGL_HEIGHT, size,
      EGL_NONE
  };

  m_pixelbufferSurface = eglCreatePbufferSurface(m_display, m_config, surfaceConfig);

  if (m_pixelbufferSurface == EGL_NO_SURFACE)
  {
    CHECK_EGL_CALL();
    return false;
  }

  return true;
}

}  // namespace android
<commit_msg>Fixed GL-context initialization for ES2-Android<commit_after>#include "androidoglcontextfactory.hpp"
#include "android_gl_utils.hpp"

#include "base/assert.hpp"
#include "base/logging.hpp"
#include "base/src_point.hpp"

#include <algorithm>

#include <EGL/egl.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>

#define EGL_OPENGL_ES3_BIT 0x00000040

namespace android
{
namespace
{
static EGLint * getConfigAttributesListRGB8(bool supportedES3)
{
  static EGLint attr_list[] = {
    EGL_RED_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    EGL_ALPHA_SIZE, 0,
    EGL_STENCIL_SIZE, 0,
    EGL_DEPTH_SIZE, 16,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
    EGL_NONE
  };
  static EGLint attr_list_es3[] = {
    EGL_RED_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    EGL_ALPHA_SIZE, 0,
    EGL_STENCIL_SIZE, 0,
    EGL_DEPTH_SIZE, 16,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
    EGL_NONE
  };
  return supportedES3 ? attr_list_es3 : attr_list;
}

int const kMaxConfigCount = 40;

static EGLint * getConfigAttributesListR5G6B5()
{
  // We do not support OpenGL ES3 for R5G6B5, because some Android devices
  // are not able to create OpenGL context in such mode.
  static EGLint attr_list[] = {
    EGL_RED_SIZE, 5,
    EGL_GREEN_SIZE, 6,
    EGL_BLUE_SIZE, 5,
    EGL_STENCIL_SIZE, 0,
    EGL_DEPTH_SIZE, 16,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
    EGL_NONE
  };
  return attr_list;
}

bool IsSupportedRGB8(EGLDisplay display, bool es3)
{
  EGLConfig configs[kMaxConfigCount];
  int count = 0;
  return eglChooseConfig(display, getConfigAttributesListRGB8(es3), configs,
                         kMaxConfigCount, &count) == EGL_TRUE && count != 0;
}
}  // namespace

AndroidOGLContextFactory::AndroidOGLContextFactory(JNIEnv * env, jobject jsurface)
  : m_drawContext(NULL)
  , m_uploadContext(NULL)
  , m_windowSurface(EGL_NO_SURFACE)
  , m_pixelbufferSurface(EGL_NO_SURFACE)
  , m_config(NULL)
  , m_nativeWindow(NULL)
  , m_display(EGL_NO_DISPLAY)
  , m_surfaceWidth(0)
  , m_surfaceHeight(0)
  , m_windowSurfaceValid(false)
  , m_supportedES3(false)
{
  m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  if (m_display == EGL_NO_DISPLAY)
  {
    CHECK_EGL_CALL();
    return;
  }

  EGLint version[2] = {0};
  if (!eglInitialize(m_display, &version[0], &version[1]))
  {
    CHECK_EGL_CALL();
    return;
  }

  m_supportedES3 = gl3stubInit() && IsSupportedRGB8(m_display, true /* es3 */);

  SetSurface(env, jsurface);

  if (!createPixelbufferSurface())
  {
    CHECK_EGL(eglTerminate(m_display));
    return;
  }
}

AndroidOGLContextFactory::~AndroidOGLContextFactory()
{
  if (m_drawContext != nullptr)
  {
    delete m_drawContext;
    m_drawContext = nullptr;
  }

  if (m_uploadContext != nullptr)
  {
    delete m_uploadContext;
    m_uploadContext = nullptr;
  }

  ResetSurface();

  if (m_pixelbufferSurface != EGL_NO_SURFACE)
  {
    eglDestroySurface(m_display, m_pixelbufferSurface);
    CHECK_EGL_CALL();
    m_pixelbufferSurface = EGL_NO_SURFACE;
  }

  if (m_display != EGL_NO_DISPLAY)
  {
    eglTerminate(m_display);
    CHECK_EGL_CALL();
  }
}

void AndroidOGLContextFactory::SetSurface(JNIEnv * env, jobject jsurface)
{
  if (!jsurface)
    return;

  m_nativeWindow = ANativeWindow_fromSurface(env, jsurface);
  if (!m_nativeWindow)
  {
    LOG(LINFO, ("Can't get native window from Java surface"));
    return;
  }

  if (!createWindowSurface())
  {
    CHECK_EGL(eglTerminate(m_display));
    return;
  }

  if (!QuerySurfaceSize())
    return;

  if (m_drawContext != nullptr)
    m_drawContext->setSurface(m_windowSurface);

  m_windowSurfaceValid = true;
}

void AndroidOGLContextFactory::ResetSurface()
{
  if (m_drawContext != nullptr)
    m_drawContext->resetSurface();

  if (IsValid())
  {
    eglDestroySurface(m_display, m_windowSurface);
    CHECK_EGL_CALL();
    m_windowSurface = EGL_NO_SURFACE;

    ANativeWindow_release(m_nativeWindow);
    m_nativeWindow = NULL;

    m_windowSurfaceValid = false;
  }
}

bool AndroidOGLContextFactory::IsValid() const
{
  return m_windowSurfaceValid && m_pixelbufferSurface != EGL_NO_SURFACE;
}

int AndroidOGLContextFactory::GetWidth() const
{
  ASSERT(IsValid(), ());
  return m_surfaceWidth;
}

int AndroidOGLContextFactory::GetHeight() const
{
  ASSERT(IsValid(), ());
  return m_surfaceHeight;
}

void AndroidOGLContextFactory::UpdateSurfaceSize()
{
  ASSERT(IsValid(), ());
  QuerySurfaceSize();
}

bool AndroidOGLContextFactory::QuerySurfaceSize()
{
  EGLint queryResult;
  if (eglQuerySurface(m_display, m_windowSurface, EGL_WIDTH, &queryResult) == EGL_FALSE)
  {
    CHECK_EGL_CALL();
    return false;
  }

  m_surfaceWidth = static_cast<int>(queryResult);
  if (eglQuerySurface(m_display, m_windowSurface, EGL_HEIGHT, &queryResult) == EGL_FALSE)
  {
    CHECK_EGL_CALL();
    return false;
  }

  m_surfaceHeight = static_cast<int>(queryResult);
  return true;
}

dp::OGLContext * AndroidOGLContextFactory::getDrawContext()
{
  ASSERT(IsValid(), ());
  ASSERT(m_windowSurface != EGL_NO_SURFACE, ());
  if (m_drawContext == nullptr)
  {
    m_drawContext = new AndroidOGLContext(m_supportedES3, m_display, m_windowSurface,
                                          m_config, m_uploadContext);
  }
  return m_drawContext;
}

dp::OGLContext * AndroidOGLContextFactory::getResourcesUploadContext()
{
  ASSERT(IsValid(), ());
  ASSERT(m_pixelbufferSurface != EGL_NO_SURFACE, ());
  if (m_uploadContext == nullptr)
  {
    m_uploadContext = new AndroidOGLContext(m_supportedES3, m_display, m_pixelbufferSurface,
                                            m_config, m_drawContext);
  }
  return m_uploadContext;
}

bool AndroidOGLContextFactory::isDrawContextCreated() const
{
  return m_drawContext != nullptr;
}

bool AndroidOGLContextFactory::isUploadContextCreated() const
{
  return m_uploadContext != nullptr;
}

bool AndroidOGLContextFactory::createWindowSurface()
{
  EGLConfig configs[kMaxConfigCount];
  int count = 0;
  if (eglChooseConfig(m_display, getConfigAttributesListRGB8(m_supportedES3), configs,
                      kMaxConfigCount, &count) != EGL_TRUE)
  {
    ASSERT(!m_supportedES3, ());
    VERIFY(eglChooseConfig(m_display, getConfigAttributesListR5G6B5(), configs,
                                      kMaxConfigCount, &count) == EGL_TRUE, ());
    LOG(LDEBUG, ("Backbuffer format: R5G6B5"));
  }
  else
  {
    LOG(LDEBUG, ("Backbuffer format: RGB8"));
  }
  ASSERT(count > 0, ("Didn't find any configs."));

  std::sort(&configs[0], &configs[count], ConfigComparator(m_display));
  for (int i = 0; i < count; ++i)
  {
    EGLConfig currentConfig = configs[i];

    EGLint format;
    eglGetConfigAttrib(m_display, currentConfig, EGL_NATIVE_VISUAL_ID, &format);
    ANativeWindow_setBuffersGeometry(m_nativeWindow, 0, 0, format);

    EGLint surfaceAttributes[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
    m_windowSurface = eglCreateWindowSurface(m_display, currentConfig, m_nativeWindow, surfaceAttributes);
    if (m_windowSurface == EGL_NO_SURFACE)
      continue;
    else
      m_config = currentConfig;

    break;
  }

  if (m_windowSurface == EGL_NO_SURFACE)
  {
    CHECK_EGL_CALL();
    return false;
  }

  return true;
}

bool AndroidOGLContextFactory::createPixelbufferSurface()
{
  //ASSERT(m_config != NULL, ());

  const GLuint size = 1; // yes, 1 is the correct size, we dont really draw on it
  static EGLint surfaceConfig[] = {
      EGL_WIDTH, size,
      EGL_HEIGHT, size,
      EGL_NONE
  };

  m_pixelbufferSurface = eglCreatePbufferSurface(m_display, m_config, surfaceConfig);

  if (m_pixelbufferSurface == EGL_NO_SURFACE)
  {
    CHECK_EGL_CALL();
    return false;
  }

  return true;
}

}  // namespace android
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/
#include <osgUtil/RenderBin>
#include <osgUtil/RenderStage>

#include <osg/Statistics>
#include <osg/ImpostorSprite>
#include <osg/Notify>

#include <algorithm>

using namespace osg;
using namespace osgUtil;

class RenderBinPrototypeList : public osg::Referenced, public std::map< std::string, osg::ref_ptr<RenderBin> >
{
    public:
	RenderBinPrototypeList() {osg::notify(osg::DEBUG_INFO)<<"constructing RenderBinPrototypeList"<<std::endl;}
	~RenderBinPrototypeList() { osg::notify(osg::DEBUG_INFO)<<"destructing RenderBinPrototypeList"<<std::endl;}
};

// register a RenderStage prototype with the RenderBin prototype list.
RegisterRenderBinProxy s_registerRenderBinProxy("RenderBin",new RenderBin(RenderBin::SORT_BY_STATE));
RegisterRenderBinProxy s_registerDepthSortedBinProxy("DepthSortedBin",new RenderBin(RenderBin::SORT_BACK_TO_FRONT));

RenderBinPrototypeList* renderBinPrototypeList()
{
    static osg::ref_ptr<RenderBinPrototypeList> s_renderBinPrototypeList = new  RenderBinPrototypeList;
    return s_renderBinPrototypeList.get();
}

RenderBin* RenderBin::getRenderBinPrototype(const std::string& binName)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list)
    {
        RenderBinPrototypeList::iterator itr = list->find(binName);
        if (itr != list->end()) return itr->second.get();
    }
    return NULL;
}

RenderBin* RenderBin::createRenderBin(const std::string& binName)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list)
    {
        RenderBin* prototype = getRenderBinPrototype(binName);
        if (prototype) return dynamic_cast<RenderBin*>(prototype->clone(osg::CopyOp::DEEP_COPY_ALL));
    }
    return NULL;
}

void RenderBin::addRenderBinPrototype(const std::string& binName,RenderBin* proto)
{
    osg::notify(osg::DEBUG_INFO)<<"addRenderBinPrototype "<<proto<<std::endl;
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list && proto)
    {
        (*list)[binName] = proto;
    }
}

void RenderBin::removeRenderBinPrototype(RenderBin* proto)
{
    osg::notify(osg::DEBUG_INFO)<<"removeRenderBinPrototype "<<proto<<std::endl;
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list && proto)
    {
        RenderBinPrototypeList::iterator itr = list->find(proto->className());
        if (itr != list->end()) list->erase(itr);
    }
}

RenderBin::RenderBin(SortMode mode)
{
    _binNum = 0;
    _parent = NULL;
    _stage = NULL;
    _sortMode = mode;
}

RenderBin::RenderBin(const RenderBin& rhs,const CopyOp& copyop):
        Object(rhs,copyop),
        _binNum(rhs._binNum),
        _parent(rhs._parent),
        _stage(rhs._stage),
        _bins(rhs._bins),
        _renderGraphList(rhs._renderGraphList),
        _renderLeafList(rhs._renderLeafList),
        _sortMode(rhs._sortMode),
        _sortCallback(rhs._sortCallback),
        _drawCallback(rhs._drawCallback)
{

}

RenderBin::~RenderBin()
{
}

void RenderBin::reset()
{
    _renderGraphList.clear();
    _bins.clear();
}

void RenderBin::sort()
{
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        itr->second->sort();
    }

    if (_sortCallback.valid())
    {
        _sortCallback->sortImplementation(this);
    }
    else sortImplementation();
}

void RenderBin::setSortMode(SortMode mode)
{
    _sortMode = mode;
}

void RenderBin::sortImplementation()
{
    switch(_sortMode)
    {
        case(SORT_BY_STATE):
            sortByState();
            break;
        case(SORT_FRONT_TO_BACK):
            sortFrontToBack();
            break;
        case(SORT_BACK_TO_FRONT):
            sortBackToFront();
            break;
        default:
            break;
    }
}

struct SortByStateFunctor
{
    bool operator() (const RenderGraph* lhs,const RenderGraph* rhs) const
    {
        return (*(lhs->_stateset)<*(rhs->_stateset));
    }
};

void RenderBin::sortByState()
{
    // actually we'll do nothing right now, as fine grained sorting by state
    // appears to cost more to do than it saves in draw.  The contents of
    // the RenderGraph leaves is already coasrse grained sorted, this
    // sorting is as a function of the cull traversal.
    // cout << "doing sortByState "<<this<<endl;
}

struct FrontToBackSortFunctor
{
    bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const
    {
        return (lhs->_depth<rhs->_depth);
    }
};

void RenderBin::sortFrontToBack()
{
    copyLeavesFromRenderGraphListToRenderLeafList();

    // now sort the list into acending depth order.
    std::sort(_renderLeafList.begin(),_renderLeafList.end(),FrontToBackSortFunctor());

//    cout << "sort front to back"<<endl;
}

struct BackToFrontSortFunctor
{
    bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const
    {
        return (rhs->_depth<lhs->_depth);
    }
};

void RenderBin::sortBackToFront()
{
    copyLeavesFromRenderGraphListToRenderLeafList();

    // now sort the list into acending depth order.
    std::sort(_renderLeafList.begin(),_renderLeafList.end(),BackToFrontSortFunctor());

//    cout << "sort back to front"<<endl;
}

void RenderBin::copyLeavesFromRenderGraphListToRenderLeafList()
{
    _renderLeafList.clear();

    int totalsize=0;
    RenderGraphList::iterator itr;
    for(itr=_renderGraphList.begin();
        itr!=_renderGraphList.end();
        ++itr)
    {
        totalsize += (*itr)->_leaves.size();
    }

    _renderLeafList.reserve(totalsize);

    // first copy all the leaves from the render graphs into the leaf list.
    for(itr=_renderGraphList.begin();
        itr!=_renderGraphList.end();
        ++itr)
    {
        for(RenderGraph::LeafList::iterator dw_itr = (*itr)->_leaves.begin();
            dw_itr != (*itr)->_leaves.end();
            ++dw_itr)
        {
            _renderLeafList.push_back(dw_itr->get());
        }
    }

    // empty the render graph list to prevent it being drawn along side the render leaf list (see drawImplementation.)
    _renderGraphList.clear();
}

RenderBin* RenderBin::find_or_insert(int binNum,const std::string& binName)
{
    // search for appropriate bin.
    RenderBinList::iterator itr = _bins.find(binNum);
    if (itr!=_bins.end()) return itr->second.get();

    // create a renderin bin and insert into bin list.
    RenderBin* rb = RenderBin::createRenderBin(binName);
    if (rb)
    {

        RenderStage* rs = dynamic_cast<RenderStage*>(rb);
        if (rs)
        {
            rs->_binNum = binNum;
            rs->_parent = NULL;
            rs->_stage = rs;
            _stage->addToDependencyList(rs);
        }
        else
        {
            rb->_binNum = binNum;
            rb->_parent = this;
            rb->_stage = _stage;
            _bins[binNum] = rb;
        }
    }
    return rb;
}

void RenderBin::draw(osg::State& state,RenderLeaf*& previous)
{
    if (_drawCallback.valid())
    {
        _drawCallback->drawImplementation(this,state,previous);
    }
    else drawImplementation(state,previous);
}

void RenderBin::drawImplementation(osg::State& state,RenderLeaf*& previous)
{
    // draw first set of draw bins.
    RenderBinList::iterator rbitr;
    for(rbitr = _bins.begin();
        rbitr!=_bins.end() && rbitr->first<0;
        ++rbitr)
    {
        rbitr->second->draw(state,previous);
    }

    // draw fine grained ordering.
    for(RenderLeafList::iterator rlitr= _renderLeafList.begin();
        rlitr!= _renderLeafList.end();
        ++rlitr)
    {
        RenderLeaf* rl = *rlitr;
        rl->render(state,previous);
        previous = rl;
    }

    // draw coarse grained ordering.
    for(RenderGraphList::iterator oitr=_renderGraphList.begin();
        oitr!=_renderGraphList.end();
        ++oitr)
    {

        for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
            dw_itr != (*oitr)->_leaves.end();
            ++dw_itr)
        {
            RenderLeaf* rl = dw_itr->get();
            rl->render(state,previous);
            previous = rl;

        }
    }

    // draw post bins.
    for(;
        rbitr!=_bins.end();
        ++rbitr)
    {
        rbitr->second->draw(state,previous);
    }

}

// stats
bool RenderBin::getStats(osg::Statistics* primStats)
{ // different by return type - collects the stats in this renderrBin
    bool somestats=false;
    for(RenderGraphList::iterator oitr=_renderGraphList.begin();
        oitr!=_renderGraphList.end();
        ++oitr)
    {

        for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
            dw_itr != (*oitr)->_leaves.end();
            ++dw_itr)
        {
            RenderLeaf* rl = dw_itr->get();
            Drawable* dw= rl->_drawable;
            primStats->addDrawable(); // number of geosets
            if (rl->_modelview.get()) primStats->addMatrix(); // number of matrices
            if (dw)
            {
                // then tot up the primtive types and no vertices.
                dw->accept(*primStats); // use sub-class to find the stats for each drawable
                if (typeid(*dw)==typeid(osg::ImpostorSprite)) primStats->addImpostor(1);
            }
        }
        somestats=true;
    }
    return somestats;
}

void RenderBin::getPrims(osg::Statistics* primStats)
{
    static int ndepth;
    ndepth++;
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        primStats->addBins(1);
        itr->second->getPrims(primStats);
    }
    getStats(primStats);
    ndepth--;

}

bool RenderBin::getPrims(osg::Statistics* primStats, int nbin)
{ // collect stats for array of bins, maximum nbin
    // (which will be modified on next call if array of primStats is too small);
    // return 1 for OK;
    static int ndepth;
    bool ok=false;
    ndepth++;
    int nb=primStats[0].getBins();
    if (nb<nbin)
    { // if statement to protect against writing to bins beyond the maximum seen before
        primStats[nb].setBinNo(nb);
        primStats[nb].setDepth(ndepth);
        getStats(primStats+nb);
    }
    primStats[0].addBins(1);
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        if (itr->second->getPrims(primStats, nbin)) ok = true;
    }
    ok=true;
    ndepth--;
    return ok;
}
<commit_msg>Removed the osg::notify() calls from the RenderBin prototype construction to avoid problems under OSX with construction/deletion of std::cout/cerr.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/
#include <osgUtil/RenderBin>
#include <osgUtil/RenderStage>

#include <osg/Statistics>
#include <osg/ImpostorSprite>

#include <algorithm>

using namespace osg;
using namespace osgUtil;

class RenderBinPrototypeList : public osg::Referenced, public std::map< std::string, osg::ref_ptr<RenderBin> >
{
    public:
	RenderBinPrototypeList() {}
	~RenderBinPrototypeList() {}
};

// register a RenderStage prototype with the RenderBin prototype list.
RegisterRenderBinProxy s_registerRenderBinProxy("RenderBin",new RenderBin(RenderBin::SORT_BY_STATE));
RegisterRenderBinProxy s_registerDepthSortedBinProxy("DepthSortedBin",new RenderBin(RenderBin::SORT_BACK_TO_FRONT));

RenderBinPrototypeList* renderBinPrototypeList()
{
    static osg::ref_ptr<RenderBinPrototypeList> s_renderBinPrototypeList = new  RenderBinPrototypeList;
    return s_renderBinPrototypeList.get();
}

RenderBin* RenderBin::getRenderBinPrototype(const std::string& binName)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list)
    {
        RenderBinPrototypeList::iterator itr = list->find(binName);
        if (itr != list->end()) return itr->second.get();
    }
    return NULL;
}

RenderBin* RenderBin::createRenderBin(const std::string& binName)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list)
    {
        RenderBin* prototype = getRenderBinPrototype(binName);
        if (prototype) return dynamic_cast<RenderBin*>(prototype->clone(osg::CopyOp::DEEP_COPY_ALL));
    }
    return NULL;
}

void RenderBin::addRenderBinPrototype(const std::string& binName,RenderBin* proto)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list && proto)
    {
        (*list)[binName] = proto;
    }
}

void RenderBin::removeRenderBinPrototype(RenderBin* proto)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list && proto)
    {
        RenderBinPrototypeList::iterator itr = list->find(proto->className());
        if (itr != list->end()) list->erase(itr);
    }
}

RenderBin::RenderBin(SortMode mode)
{
    _binNum = 0;
    _parent = NULL;
    _stage = NULL;
    _sortMode = mode;
}

RenderBin::RenderBin(const RenderBin& rhs,const CopyOp& copyop):
        Object(rhs,copyop),
        _binNum(rhs._binNum),
        _parent(rhs._parent),
        _stage(rhs._stage),
        _bins(rhs._bins),
        _renderGraphList(rhs._renderGraphList),
        _renderLeafList(rhs._renderLeafList),
        _sortMode(rhs._sortMode),
        _sortCallback(rhs._sortCallback),
        _drawCallback(rhs._drawCallback)
{

}

RenderBin::~RenderBin()
{
}

void RenderBin::reset()
{
    _renderGraphList.clear();
    _bins.clear();
}

void RenderBin::sort()
{
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        itr->second->sort();
    }

    if (_sortCallback.valid())
    {
        _sortCallback->sortImplementation(this);
    }
    else sortImplementation();
}

void RenderBin::setSortMode(SortMode mode)
{
    _sortMode = mode;
}

void RenderBin::sortImplementation()
{
    switch(_sortMode)
    {
        case(SORT_BY_STATE):
            sortByState();
            break;
        case(SORT_FRONT_TO_BACK):
            sortFrontToBack();
            break;
        case(SORT_BACK_TO_FRONT):
            sortBackToFront();
            break;
        default:
            break;
    }
}

struct SortByStateFunctor
{
    bool operator() (const RenderGraph* lhs,const RenderGraph* rhs) const
    {
        return (*(lhs->_stateset)<*(rhs->_stateset));
    }
};

void RenderBin::sortByState()
{
    // actually we'll do nothing right now, as fine grained sorting by state
    // appears to cost more to do than it saves in draw.  The contents of
    // the RenderGraph leaves is already coasrse grained sorted, this
    // sorting is as a function of the cull traversal.
    // cout << "doing sortByState "<<this<<endl;
}

struct FrontToBackSortFunctor
{
    bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const
    {
        return (lhs->_depth<rhs->_depth);
    }
};

void RenderBin::sortFrontToBack()
{
    copyLeavesFromRenderGraphListToRenderLeafList();

    // now sort the list into acending depth order.
    std::sort(_renderLeafList.begin(),_renderLeafList.end(),FrontToBackSortFunctor());

//    cout << "sort front to back"<<endl;
}

struct BackToFrontSortFunctor
{
    bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const
    {
        return (rhs->_depth<lhs->_depth);
    }
};

void RenderBin::sortBackToFront()
{
    copyLeavesFromRenderGraphListToRenderLeafList();

    // now sort the list into acending depth order.
    std::sort(_renderLeafList.begin(),_renderLeafList.end(),BackToFrontSortFunctor());

//    cout << "sort back to front"<<endl;
}

void RenderBin::copyLeavesFromRenderGraphListToRenderLeafList()
{
    _renderLeafList.clear();

    int totalsize=0;
    RenderGraphList::iterator itr;
    for(itr=_renderGraphList.begin();
        itr!=_renderGraphList.end();
        ++itr)
    {
        totalsize += (*itr)->_leaves.size();
    }

    _renderLeafList.reserve(totalsize);

    // first copy all the leaves from the render graphs into the leaf list.
    for(itr=_renderGraphList.begin();
        itr!=_renderGraphList.end();
        ++itr)
    {
        for(RenderGraph::LeafList::iterator dw_itr = (*itr)->_leaves.begin();
            dw_itr != (*itr)->_leaves.end();
            ++dw_itr)
        {
            _renderLeafList.push_back(dw_itr->get());
        }
    }

    // empty the render graph list to prevent it being drawn along side the render leaf list (see drawImplementation.)
    _renderGraphList.clear();
}

RenderBin* RenderBin::find_or_insert(int binNum,const std::string& binName)
{
    // search for appropriate bin.
    RenderBinList::iterator itr = _bins.find(binNum);
    if (itr!=_bins.end()) return itr->second.get();

    // create a renderin bin and insert into bin list.
    RenderBin* rb = RenderBin::createRenderBin(binName);
    if (rb)
    {

        RenderStage* rs = dynamic_cast<RenderStage*>(rb);
        if (rs)
        {
            rs->_binNum = binNum;
            rs->_parent = NULL;
            rs->_stage = rs;
            _stage->addToDependencyList(rs);
        }
        else
        {
            rb->_binNum = binNum;
            rb->_parent = this;
            rb->_stage = _stage;
            _bins[binNum] = rb;
        }
    }
    return rb;
}

void RenderBin::draw(osg::State& state,RenderLeaf*& previous)
{
    if (_drawCallback.valid())
    {
        _drawCallback->drawImplementation(this,state,previous);
    }
    else drawImplementation(state,previous);
}

void RenderBin::drawImplementation(osg::State& state,RenderLeaf*& previous)
{
    // draw first set of draw bins.
    RenderBinList::iterator rbitr;
    for(rbitr = _bins.begin();
        rbitr!=_bins.end() && rbitr->first<0;
        ++rbitr)
    {
        rbitr->second->draw(state,previous);
    }

    // draw fine grained ordering.
    for(RenderLeafList::iterator rlitr= _renderLeafList.begin();
        rlitr!= _renderLeafList.end();
        ++rlitr)
    {
        RenderLeaf* rl = *rlitr;
        rl->render(state,previous);
        previous = rl;
    }

    // draw coarse grained ordering.
    for(RenderGraphList::iterator oitr=_renderGraphList.begin();
        oitr!=_renderGraphList.end();
        ++oitr)
    {

        for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
            dw_itr != (*oitr)->_leaves.end();
            ++dw_itr)
        {
            RenderLeaf* rl = dw_itr->get();
            rl->render(state,previous);
            previous = rl;

        }
    }

    // draw post bins.
    for(;
        rbitr!=_bins.end();
        ++rbitr)
    {
        rbitr->second->draw(state,previous);
    }

}

// stats
bool RenderBin::getStats(osg::Statistics* primStats)
{ // different by return type - collects the stats in this renderrBin
    bool somestats=false;
    for(RenderGraphList::iterator oitr=_renderGraphList.begin();
        oitr!=_renderGraphList.end();
        ++oitr)
    {

        for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
            dw_itr != (*oitr)->_leaves.end();
            ++dw_itr)
        {
            RenderLeaf* rl = dw_itr->get();
            Drawable* dw= rl->_drawable;
            primStats->addDrawable(); // number of geosets
            if (rl->_modelview.get()) primStats->addMatrix(); // number of matrices
            if (dw)
            {
                // then tot up the primtive types and no vertices.
                dw->accept(*primStats); // use sub-class to find the stats for each drawable
                if (typeid(*dw)==typeid(osg::ImpostorSprite)) primStats->addImpostor(1);
            }
        }
        somestats=true;
    }
    return somestats;
}

void RenderBin::getPrims(osg::Statistics* primStats)
{
    static int ndepth;
    ndepth++;
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        primStats->addBins(1);
        itr->second->getPrims(primStats);
    }
    getStats(primStats);
    ndepth--;

}

bool RenderBin::getPrims(osg::Statistics* primStats, int nbin)
{ // collect stats for array of bins, maximum nbin
    // (which will be modified on next call if array of primStats is too small);
    // return 1 for OK;
    static int ndepth;
    bool ok=false;
    ndepth++;
    int nb=primStats[0].getBins();
    if (nb<nbin)
    { // if statement to protect against writing to bins beyond the maximum seen before
        primStats[nb].setBinNo(nb);
        primStats[nb].setDepth(ndepth);
        getStats(primStats+nb);
    }
    primStats[0].addBins(1);
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        if (itr->second->getPrims(primStats, nbin)) ok = true;
    }
    ok=true;
    ndepth--;
    return ok;
}
<|endoftext|>


<commit_before>// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/v8.h"

#include "src/version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     27
#define BUILD_NUMBER      9999
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 1

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    SNPrintF(str, "%d.%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
             is_simulator);
  } else {
    SNPrintF(str, "%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), candidate,
             is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      SNPrintF(str, "libv8-%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<commit_msg>[Auto-roll] Bump up version to 3.28.26.0<commit_after>// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/v8.h"

#include "src/version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     28
#define BUILD_NUMBER      26
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 1

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    SNPrintF(str, "%d.%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
             is_simulator);
  } else {
    SNPrintF(str, "%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), candidate,
             is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      SNPrintF(str, "libv8-%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<|endoftext|>


<commit_before>// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/v8.h"

#include "src/version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     29
#define BUILD_NUMBER      49
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 1

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    SNPrintF(str, "%d.%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
             is_simulator);
  } else {
    SNPrintF(str, "%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), candidate,
             is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      SNPrintF(str, "libv8-%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<commit_msg>[Auto-roll] Bump up version to 3.29.51.0<commit_after>// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/v8.h"

#include "src/version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     29
#define BUILD_NUMBER      51
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 1

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    SNPrintF(str, "%d.%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
             is_simulator);
  } else {
    SNPrintF(str, "%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), candidate,
             is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      SNPrintF(str, "libv8-%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<|endoftext|>


<commit_before>// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "v8.h"

#include "version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     25
#define BUILD_NUMBER      19
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 1

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    OS::SNPrintF(str, "%d.%d.%d.%d%s%s",
                 GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
                 is_simulator);
  } else {
    OS::SNPrintF(str, "%d.%d.%d%s%s",
                 GetMajor(), GetMinor(), GetBuild(), candidate,
                 is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      OS::SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
                   GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      OS::SNPrintF(str, "libv8-%d.%d.%d%s.so",
                   GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    OS::SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<commit_msg>Prepare push to trunk.  Now working on version 3.25.20.<commit_after>// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "v8.h"

#include "version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     25
#define BUILD_NUMBER      20
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    OS::SNPrintF(str, "%d.%d.%d.%d%s%s",
                 GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
                 is_simulator);
  } else {
    OS::SNPrintF(str, "%d.%d.%d%s%s",
                 GetMajor(), GetMinor(), GetBuild(), candidate,
                 is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      OS::SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
                   GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      OS::SNPrintF(str, "libv8-%d.%d.%d%s.so",
                   GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    OS::SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<|endoftext|>


<commit_before>#include <QtGui>
#include "window.h"

SettingsTab::SettingsTab(QWidget *parent)
  : QWidget(parent)
{

  QLabel *usernameLabel = new QLabel(tr("Username:"));
  username = new QLineEdit;
  usernameLabel->setBuddy(username);

  QLabel *passwordLabel = new QLabel(tr("Password:"));
  password = new QLineEdit;
  passwordLabel->setBuddy(password);

  QLabel *webserviceUrlLabel = new QLabel(tr("Webservice URL:"));
  webserviceUrl = new QLineEdit;
  webserviceUrlLabel->setBuddy(webserviceUrl);

  QGridLayout *layout = new QGridLayout;
  setLayout(layout);
  layout->setVerticalSpacing(15);

  layout->addWidget(webserviceUrlLabel, 0, 0);
  layout->addWidget(webserviceUrl, 0, 1);

  layout->addWidget(usernameLabel, 1, 0);
  layout->addWidget(username, 1, 1);

  layout->addWidget(passwordLabel, 2, 0);

#ifndef _DEBUG
  webserviceUrlLabel->hide();
  webserviceUrl->hide();
#endif

  QHBoxLayout *row = new QHBoxLayout;
  QPushButton *revealButton = new QPushButton(tr("Reveal"));
  connect(revealButton, SIGNAL(clicked()), this, SLOT(reveal()));

  row->addWidget(password);
  row->addWidget(revealButton);
  layout->addLayout(row, 2, 1);

  QFrame *line = new QFrame;
  line->setObjectName(QString::fromUtf8("line"));
  line->setFrameShape(QFrame::HLine);
  line->setFrameShadow(QFrame::Sunken);
  layout->addWidget(line, 3, 0, 1, 3);

  QLabel *systemLabel = new QLabel(tr("System:"));
  layout->addWidget(systemLabel, 5, 0);

  startAtLogin = new QCheckBox(tr("Start at Login"));
  layout->addWidget(startAtLogin, 5, 1);

  QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
  layout->addItem(spacer, 6, 0);

  QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  connect(buttonBox, SIGNAL(accepted()), this, SLOT(ok()));
  connect(buttonBox, SIGNAL(rejected()), this, SLOT(cancel()));
  layout->addWidget(buttonBox, 7, 0, 1, 3);
}

void SettingsTab::reveal() {
  password->setEchoMode(QLineEdit::Normal);
}

void SettingsTab::conceal() {
  password->setEchoMode(QLineEdit::Password);
}

void SettingsTab::updateSettings() {
  Autostart autostart;

  username->setText(Tracker::Instance()->Username());
  password->setText(Tracker::Instance()->Password());
  webserviceUrl->setText(Tracker::Instance()->WebserviceURL());
  conceal();

  startAtLogin->setChecked(autostart.IsActive());
}

void SettingsTab::applySettings() {
  Autostart autostart;

  Tracker::Instance()->SetUsername(username->text());
  Tracker::Instance()->SetPassword(password->text());
  Tracker::Instance()->SetWebserviceURL(webserviceUrl->text());
  autostart.SetActive(startAtLogin->isChecked());
}

void SettingsTab::ok() {
  applySettings();
  window()->hide();
}

void SettingsTab::cancel() {
  window()->hide();
}

LogTab::LogTab(QWidget *parent)
  : QWidget(parent)
{
  QVBoxLayout *layout = new QVBoxLayout;

  logText = new QTextEdit;
  QFont font("Monospace");
  font.setStyleHint(QFont::TypeWriter);
  logText->setFont(font);
  logText->setReadOnly(true);
  layout->addWidget(logText);

  setLayout(layout);

  connect(Logger::Instance(), SIGNAL(NewMessage(const string&)), this, SLOT(addLogEntry(const string&)));
}

void LogTab::addLogEntry(const string& msg) {
  logText->moveCursor(QTextCursor::End);
  logText->insertPlainText(msg.c_str());
  logText->moveCursor(QTextCursor::End);
}

AboutTab::AboutTab(QWidget *parent)
  : QWidget(parent)
{
  QVBoxLayout *layout = new QVBoxLayout;

  QSpacerItem *topSpacer = new QSpacerItem(40, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
  QSpacerItem *bottomSpacer = new QSpacerItem(40, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);

  QLabel *name = new QLabel(qApp->applicationName());
  name->setStyleSheet("QLabel { font-size: 20px; }");
  name->setAlignment(Qt::AlignHCenter);

  QLabel *slogan = new QLabel("The friendly Hearthstone Tracker");
  slogan->setStyleSheet("QLabel { font-style: italic; }");
  slogan->setAlignment(Qt::AlignHCenter);

  QLabel *version = new QLabel(VERSION);
  version->setAlignment(Qt::AlignHCenter);

  QPixmap logoImage(":/icons/logo.png");
  QLabel *logo = new QLabel();
  logo->setAlignment(Qt::AlignHCenter);
  logo->setPixmap(logoImage.scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));

  layout->addItem(topSpacer);
  layout->addWidget(logo);
  layout->addWidget(name);
  layout->addWidget(slogan);
  layout->addWidget(version);
  layout->addItem(bottomSpacer);

  setLayout(layout);
}

Window::Window()
{
  setWindowTitle(qApp->applicationName());

  createActions();
  createTrayIcon();

  tabWidget = new QTabWidget;
  settingsTab = new SettingsTab;
  logTab = new LogTab;
  aboutTab = new AboutTab;

  tabWidget->addTab(settingsTab, tr("Settings"));
  tabWidget->addTab(logTab, tr("Log"));
  tabWidget->addTab(aboutTab, tr("About"));

  QVBoxLayout *mainLayout = new QVBoxLayout;
  mainLayout->setSizeConstraint(QLayout::SetNoConstraint);
  mainLayout->addWidget(tabWidget);

  setLayout(mainLayout);

  setMinimumSize(450, 250);
  resize(minimumSize());
}

Window::~Window() {
}

void Window::showEvent(QShowEvent *event) {
  QDialog::showEvent(event);
  settingsTab->updateSettings();
}

void Window::closeEvent(QCloseEvent *event) {
  if(trayIcon->isVisible()) {
    hide();
    event->ignore();
  }
}

// prevent esc from closing the app
void Window::reject()
{
  if(trayIcon->isVisible()) {
    hide();
  } else {
    QDialog::reject();
  }
}

void Window::createActions()
{
  openProfileAction = new QAction(tr("Open Profile..."), this);
  connect(openProfileAction, SIGNAL(triggered()), this, SLOT(openProfile()));

  showAction = new QAction(tr("Settings..."), this);
  connect(showAction, SIGNAL(triggered()), this, SLOT(riseAndShine()));

  quitAction = new QAction(tr("Quit"), this);
  connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
}

void Window::createTrayIcon()
{
  trayIconMenu = new QMenu(this);
  trayIconMenu->addAction(openProfileAction);
  trayIconMenu->addSeparator();
  trayIconMenu->addAction(showAction);
  trayIconMenu->addSeparator();
  trayIconMenu->addAction(quitAction);

  trayIcon = new QSystemTrayIcon(this);
  trayIcon->setContextMenu(trayIconMenu);

#ifdef Q_WS_MAC
  QIcon icon = QIcon(":/icons/tray_mac.png");
  icon.addFile(":/icons/tray_mac_selected.png", QSize(), QIcon::Selected);
#elif defined Q_WS_WIN
  QIcon icon = QIcon(":/icons/tray_win.png");
#endif

  trayIcon->setIcon(icon);
  trayIcon->show();
}

void Window::riseAndShine() {
  show();
  raise();
}

void Window::openProfile() {
  Tracker::Instance()->OpenProfile();
}
<commit_msg>disable alteration of login credentials for the moment<commit_after>#include <QtGui>
#include "window.h"

SettingsTab::SettingsTab(QWidget *parent)
  : QWidget(parent)
{

  QLabel *usernameLabel = new QLabel(tr("Username:"));
  username = new QLineEdit;
  username->setReadOnly(true);
  usernameLabel->setBuddy(username);

  QLabel *passwordLabel = new QLabel(tr("Password:"));
  password = new QLineEdit;
  password->setReadOnly(true);
  passwordLabel->setBuddy(password);

  QLabel *webserviceUrlLabel = new QLabel(tr("Webservice URL:"));
  webserviceUrl = new QLineEdit;
  webserviceUrlLabel->setBuddy(webserviceUrl);

  QGridLayout *layout = new QGridLayout;
  setLayout(layout);
  layout->setVerticalSpacing(15);

  layout->addWidget(webserviceUrlLabel, 0, 0);
  layout->addWidget(webserviceUrl, 0, 1);

  layout->addWidget(usernameLabel, 1, 0);
  layout->addWidget(username, 1, 1);

  layout->addWidget(passwordLabel, 2, 0);

#ifndef _DEBUG
  webserviceUrlLabel->hide();
  webserviceUrl->hide();
#endif

  QHBoxLayout *row = new QHBoxLayout;
  QPushButton *revealButton = new QPushButton(tr("Reveal"));
  connect(revealButton, SIGNAL(clicked()), this, SLOT(reveal()));

  row->addWidget(password);
  row->addWidget(revealButton);
  layout->addLayout(row, 2, 1);

  QFrame *line = new QFrame;
  line->setObjectName(QString::fromUtf8("line"));
  line->setFrameShape(QFrame::HLine);
  line->setFrameShadow(QFrame::Sunken);
  layout->addWidget(line, 3, 0, 1, 3);

  QLabel *systemLabel = new QLabel(tr("System:"));
  layout->addWidget(systemLabel, 5, 0);

  startAtLogin = new QCheckBox(tr("Start at Login"));
  layout->addWidget(startAtLogin, 5, 1);

  QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
  layout->addItem(spacer, 6, 0);

  QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  connect(buttonBox, SIGNAL(accepted()), this, SLOT(ok()));
  connect(buttonBox, SIGNAL(rejected()), this, SLOT(cancel()));
  layout->addWidget(buttonBox, 7, 0, 1, 3);
}

void SettingsTab::reveal() {
  password->setEchoMode(QLineEdit::Normal);
}

void SettingsTab::conceal() {
  password->setEchoMode(QLineEdit::Password);
}

void SettingsTab::updateSettings() {
  Autostart autostart;

  username->setText(Tracker::Instance()->Username());
  password->setText(Tracker::Instance()->Password());
  webserviceUrl->setText(Tracker::Instance()->WebserviceURL());
  conceal();

  startAtLogin->setChecked(autostart.IsActive());
}

void SettingsTab::applySettings() {
  Autostart autostart;

  Tracker::Instance()->SetUsername(username->text());
  Tracker::Instance()->SetPassword(password->text());
  Tracker::Instance()->SetWebserviceURL(webserviceUrl->text());
  autostart.SetActive(startAtLogin->isChecked());
}

void SettingsTab::ok() {
  applySettings();
  window()->hide();
}

void SettingsTab::cancel() {
  window()->hide();
}

LogTab::LogTab(QWidget *parent)
  : QWidget(parent)
{
  QVBoxLayout *layout = new QVBoxLayout;

  logText = new QTextEdit;
  QFont font("Monospace");
  font.setStyleHint(QFont::TypeWriter);
  logText->setFont(font);
  logText->setReadOnly(true);
  layout->addWidget(logText);

  setLayout(layout);

  connect(Logger::Instance(), SIGNAL(NewMessage(const string&)), this, SLOT(addLogEntry(const string&)));
}

void LogTab::addLogEntry(const string& msg) {
  logText->moveCursor(QTextCursor::End);
  logText->insertPlainText(msg.c_str());
  logText->moveCursor(QTextCursor::End);
}

AboutTab::AboutTab(QWidget *parent)
  : QWidget(parent)
{
  QVBoxLayout *layout = new QVBoxLayout;

  QSpacerItem *topSpacer = new QSpacerItem(40, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
  QSpacerItem *bottomSpacer = new QSpacerItem(40, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);

  QLabel *name = new QLabel(qApp->applicationName());
  name->setStyleSheet("QLabel { font-size: 20px; }");
  name->setAlignment(Qt::AlignHCenter);

  QLabel *slogan = new QLabel("The friendly Hearthstone Tracker");
  slogan->setStyleSheet("QLabel { font-style: italic; }");
  slogan->setAlignment(Qt::AlignHCenter);

  QLabel *version = new QLabel(VERSION);
  version->setAlignment(Qt::AlignHCenter);

  QPixmap logoImage(":/icons/logo.png");
  QLabel *logo = new QLabel();
  logo->setAlignment(Qt::AlignHCenter);
  logo->setPixmap(logoImage.scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));

  layout->addItem(topSpacer);
  layout->addWidget(logo);
  layout->addWidget(name);
  layout->addWidget(slogan);
  layout->addWidget(version);
  layout->addItem(bottomSpacer);

  setLayout(layout);
}

Window::Window()
{
  setWindowTitle(qApp->applicationName());

  createActions();
  createTrayIcon();

  tabWidget = new QTabWidget;
  settingsTab = new SettingsTab;
  logTab = new LogTab;
  aboutTab = new AboutTab;

  tabWidget->addTab(settingsTab, tr("Settings"));
  tabWidget->addTab(logTab, tr("Log"));
  tabWidget->addTab(aboutTab, tr("About"));

  QVBoxLayout *mainLayout = new QVBoxLayout;
  mainLayout->setSizeConstraint(QLayout::SetNoConstraint);
  mainLayout->addWidget(tabWidget);

  setLayout(mainLayout);

  setMinimumSize(450, 250);
  resize(minimumSize());
}

Window::~Window() {
}

void Window::showEvent(QShowEvent *event) {
  QDialog::showEvent(event);
  settingsTab->updateSettings();
}

void Window::closeEvent(QCloseEvent *event) {
  if(trayIcon->isVisible()) {
    hide();
    event->ignore();
  }
}

// prevent esc from closing the app
void Window::reject()
{
  if(trayIcon->isVisible()) {
    hide();
  } else {
    QDialog::reject();
  }
}

void Window::createActions()
{
  openProfileAction = new QAction(tr("Open Profile..."), this);
  connect(openProfileAction, SIGNAL(triggered()), this, SLOT(openProfile()));

  showAction = new QAction(tr("Settings..."), this);
  connect(showAction, SIGNAL(triggered()), this, SLOT(riseAndShine()));

  quitAction = new QAction(tr("Quit"), this);
  connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
}

void Window::createTrayIcon()
{
  trayIconMenu = new QMenu(this);
  trayIconMenu->addAction(openProfileAction);
  trayIconMenu->addSeparator();
  trayIconMenu->addAction(showAction);
  trayIconMenu->addSeparator();
  trayIconMenu->addAction(quitAction);

  trayIcon = new QSystemTrayIcon(this);
  trayIcon->setContextMenu(trayIconMenu);

#ifdef Q_WS_MAC
  QIcon icon = QIcon(":/icons/tray_mac.png");
  icon.addFile(":/icons/tray_mac_selected.png", QSize(), QIcon::Selected);
#elif defined Q_WS_WIN
  QIcon icon = QIcon(":/icons/tray_win.png");
#endif

  trayIcon->setIcon(icon);
  trayIcon->show();
}

void Window::riseAndShine() {
  show();
  raise();
}

void Window::openProfile() {
  Tracker::Instance()->OpenProfile();
}
<|endoftext|>