<commit_before>#ifndef RBX_VM_H
#define RBX_VM_H

#include "missing/time.h"

#include "globals.hpp"
#include "memory/object_mark.hpp"
#include "memory/managed.hpp"
#include "vm_thread_state.hpp"
#include "thread_nexus.hpp"
#include "metrics.hpp"

#include "util/thread.hpp"

#include "memory/variable_buffer.hpp"
#include "memory/root_buffer.hpp"
#include "memory/slab.hpp"

#include "shared_state.hpp"

#include "unwind_info.hpp"
#include "fiber_stack.hpp"

#include "sodium/randombytes.h"

#include <atomic>
#include <vector>
#include <setjmp.h>
#include <stdint.h>

namespace llvm {
  class Module;
}

namespace rbxti {
  class Env;
}

namespace rubinius {

  class Exception;
  class LLVMState;

  namespace event {
    class Loop;
  }

  namespace memory {
    class GarbageCollector;
    class WriteBarrier;
  }

  class Assertion;
  class CallSiteInformation;
  class Channel;
  class CompiledCode;
  class ConfigParser;
  class Configuration;
  class Fiber;
  class GlobalCache;
  class LookupTable;
  class Memory;
  class NativeMethodEnvironment;
  class Object;
  class Park;
  class Primitives;
  class SharedState;
  class String;
  class Symbol;
  class SymbolTable;
  class Tuple;
  class TypeError;
  class TypeInfo;
  class VariableScope;

  struct CallFrame;

  enum MethodMissingReason {
    eNone, ePrivate, eProtected, eSuper, eVCall, eNormal
  };

  enum ConstantMissingReason {
    vFound, vPrivate, vNonExistent
  };

  /**
   * Represents an execution context for running Ruby code.
   *
   * Each Ruby thread is backed by an instance of this class, as well as an
   * instance of the Thread class. Thread manages the (Ruby visible) thread-
   * related state, while this class manages the execution machinery for
   * running Ruby code.
   */

  class VM : public memory::ManagedThread {
    friend class State;

  private:
    UnwindInfoSet unwinds_;

    CallFrame* call_frame_;
    ThreadNexus* thread_nexus_;
    CallSiteInformation* saved_call_site_information_;
    FiberStacks fiber_stacks_;
    Park* park_;

    void* stack_start_;
    size_t stack_size_;
    size_t stack_cushion_;

    void* current_stack_start_;
    size_t current_stack_size_;

    bool interrupt_with_signal_;
    bool interrupt_by_kill_;
    bool check_local_interrupts_;
    bool thread_step_;

    utilities::thread::SpinLock interrupt_lock_;

    MethodMissingReason method_missing_reason_;
    ConstantMissingReason constant_missing_reason_;

    bool zombie_;
    bool allocation_tracking_;
    bool main_thread_;

    std::atomic<ThreadNexus::Phase> thread_phase_;

    uint32_t profile_interval_;
    uint32_t profile_counter_;
    CompiledCode** profile_;
    uint64_t profile_sample_count_;
    uint64_t profile_report_interval_;
    native_int max_profile_entries_;
    native_int min_profile_sample_count_;

  public:
    /* Data members */
    SharedState& shared;
    memory::TypedRoot<Channel*> waiting_channel_;
    memory::TypedRoot<Exception*> interrupted_exception_;
    /// The Thread object for this VM state
    memory::TypedRoot<Thread*> thread;

    /// The current fiber running on this thread
    memory::TypedRoot<Fiber*> current_fiber;

    /// Root fiber, if any (lazily initialized)
    memory::TypedRoot<Fiber*> root_fiber;

    /// Object that waits for inflation
    memory::TypedRoot<Object*> waiting_object_;

    uint64_t start_time_;

    NativeMethodEnvironment* native_method_environment;

    void (*custom_wakeup_)(void*);
    void* custom_wakeup_data_;

    VMThreadState thread_state_;

  public: /* Inline methods */

    UnwindInfoSet& unwinds() {
      return unwinds_;
    }

    uint32_t thread_id() const {
      return id_;
    }

    ThreadNexus::Phase thread_phase() {
      return thread_phase_;
    }

    ThreadNexus* thread_nexus() {
      return thread_nexus_;
    }

    void set_thread_phase(ThreadNexus::Phase thread_phase) {
      thread_phase_ = thread_phase;
    }

    utilities::thread::SpinLock& interrupt_lock() {
      return interrupt_lock_;
    }

    void set_zombie(STATE);

    bool zombie_p() {
      return zombie_;
    }

    void set_main_thread() {
      main_thread_ = true;
    }

    bool main_thread_p() {
      return main_thread_;
    }

    VMThreadState* thread_state() {
      return &thread_state_;
    }

    Memory* memory() {
      return shared.memory();
    }

    void set_start_time();
    double run_time();

    void raise_stack_error(STATE);
    void validate_stack_size(STATE, size_t size);

    size_t stack_size() {
      return current_stack_size_;
    }

    void restore_stack_bounds() {
      current_stack_start_ = stack_start_;
      current_stack_size_ = stack_size_;
    }

    void set_stack_bounds(void* start, size_t size) {
      current_stack_start_ = start;
      current_stack_size_ = size - stack_cushion_;
    }

    void set_stack_bounds(size_t size);

    bool check_stack(STATE, void* stack_address) {
      ssize_t stack_used =
        (reinterpret_cast<intptr_t>(current_stack_start_)
        - reinterpret_cast<intptr_t>(stack_address));

      if(stack_used < 0) stack_used = -stack_used;

      if(static_cast<size_t>(stack_used) > current_stack_size_) {
        raise_stack_error(state);
        return false;
      }

      return true;
    }

    bool push_call_frame(STATE, CallFrame* frame, CallFrame*& previous_frame);

    bool pop_call_frame(STATE, CallFrame* frame) {
      call_frame_ = frame;

      return !thread_interrupted_p(state);
    }

    bool thread_interrupted_p(STATE) {
      if(check_local_interrupts()) {
        return check_thread_raise_or_kill(state);
      }

      return false;
    }

    bool check_thread_raise_or_kill(STATE);

    // Do NOT de-duplicate
    void set_call_frame(CallFrame* frame) {
      call_frame_ = frame;
    }

    CallFrame* call_frame() {
      return call_frame_;
    }

    CallFrame* get_call_frame(ssize_t up=0);
    CallFrame* get_ruby_frame(ssize_t up=0);
    CallFrame* get_variables_frame(ssize_t up=0);
    CallFrame* get_scope_frame(ssize_t up=0);

    bool scope_valid_p(VariableScope* scope);

    void set_call_site_information(CallSiteInformation* info) {
      saved_call_site_information_ = info;
    }

    CallSiteInformation* saved_call_site_information() {
      return saved_call_site_information_;
    }

    GlobalCache* global_cache() const {
      return shared.global_cache;
    }

    Globals& globals() {
      return shared.globals;
    }

    MethodMissingReason method_missing_reason() const {
      return method_missing_reason_;
    }

    void set_method_missing_reason(MethodMissingReason reason) {
      method_missing_reason_ = reason;
    }

    ConstantMissingReason constant_missing_reason() const {
      return constant_missing_reason_;
    }

    void set_constant_missing_reason(ConstantMissingReason reason) {
      constant_missing_reason_ = reason;
    }

    void after_fork_child(STATE);

    bool thread_step() const {
      return thread_step_;
    }

    void clear_thread_step() {
      clear_check_local_interrupts();
      thread_step_ = false;
    }

    void set_thread_step() {
      set_check_local_interrupts();
      thread_step_ = true;
    }

    bool check_local_interrupts() const {
      return check_local_interrupts_;
    }

    void clear_check_local_interrupts() {
      check_local_interrupts_ = false;
    }

    void set_check_local_interrupts() {
      check_local_interrupts_ = true;
    }

    bool interrupt_by_kill() const {
      return interrupt_by_kill_;
    }

    void clear_interrupt_by_kill() {
      interrupt_by_kill_ = false;
    }

    void set_interrupt_by_kill() {
      interrupt_by_kill_ = true;
    }

    Exception* interrupted_exception() const {
      return interrupted_exception_.get();
    }

    void clear_interrupted_exception() {
      interrupted_exception_.set(cNil);
    }

    bool allocation_tracking() const {
      return allocation_tracking_;
    }

    void enable_allocation_tracking() {
      allocation_tracking_ = true;
    }

    void disable_allocation_tracking() {
      allocation_tracking_ = false;
    }

    FiberStack* allocate_fiber_stack(size_t stack_size) {
      return fiber_stacks_.allocate(stack_size);
    }

    void* fiber_trampoline() {
      return fiber_stacks_.trampoline();
    }

    FiberData* new_fiber_data(size_t stack_size, bool root=false) {
      return fiber_stacks_.new_data(stack_size, root);
    }

    void remove_fiber_data(FiberData* data) {
      fiber_stacks_.remove_data(data);
    }

    memory::VariableRootBuffers& current_root_buffers();

  public:
    static VM* current();

    static void discard(STATE, VM*);

  public:

    /* Prototypes */
    VM(uint32_t id, SharedState& shared, const char* name = NULL);
    ~VM();

    void bootstrap_class(STATE);
    void bootstrap_ontology(STATE);
    void bootstrap_symbol(STATE);

    void collect_maybe(STATE);

    native_int max_profile_entries() {
      return max_profile_entries_;
    }

    uint64_t profile_sample_count() {
      return profile_sample_count_;
    }

    CompiledCode** profile() {
      return profile_;
    }

    void update_profile(STATE);
    void sort_profile();

#define RBX_PROFILE_MAX_SHIFT     0xf
#define RBX_PROFILE_MAX_INTERVAL  0x1fff

    void set_profile_interval() {
      profile_interval_ = randombytes_random();
      profile_interval_ >>= (profile_interval_ & RBX_PROFILE_MAX_SHIFT);
      profile_interval_ &= RBX_PROFILE_MAX_INTERVAL;
      profile_counter_ = 0;
    }

    void checkpoint(STATE) {
      metrics().machine.checkpoints++;

      if(thread_nexus_->try_lock(this)) {
        metrics().machine.stops++;

        collect_maybe(state);

        thread_nexus_->unlock();
      }

      if(profile_counter_++ >= profile_interval_) {
        update_profile(state);
        set_profile_interval();
      }
    }

    void blocking_suspend(STATE, metrics::metric& counter);
    void sleeping_suspend(STATE, metrics::metric& counter);

    void blocking_phase() {
      thread_nexus_->blocking_phase(this);
    }

    void managed_phase() {
      thread_nexus_->managed_phase(this);
    }

    void unmanaged_phase() {
      thread_nexus_->unmanaged_phase(this);
    }

    void set_current_thread();

    void setup_errno(STATE, int num, const char* name, Class* sce, Module* ern);
    void bootstrap_exceptions(STATE);
    void initialize_fundamental_constants(STATE);
    void initialize_builtin_classes(STATE);
    void initialize_platform_data(STATE);
    Object* ruby_lib_version();

    void set_current_fiber(Fiber* fib);

    TypeInfo* find_type(int type);

    static void init_ffi(STATE);

    void raise_from_errno(const char* reason);
    void raise_exception(Exception* exc);
    Exception* new_exception(Class* cls, const char* msg);
    Object* current_block();

    void set_const(const char* name, Object* val);
    void set_const(Module* mod, const char* name, Object* val);

    Object* path2class(const char* name);

    llvm::Module* llvm_module();
    void llvm_cleanup();

    void print_backtrace();

    void wait_on_channel(Channel* channel);
    void wait_on_inflated_lock(Object* wait);
    void wait_on_custom_function(void (*func)(void*), void* data);
    void clear_waiter();
    bool wakeup(STATE);

    void reset_parked();

    void set_sleeping();
    void clear_sleeping();

    void interrupt_with_signal() {
      interrupt_with_signal_ = true;
    }

    void register_raise(STATE, Exception* exc);
    void register_kill(STATE);

    void gc_scan(memory::GarbageCollector* gc);
    void gc_fiber_clear_mark();
    void gc_fiber_scan(memory::GarbageCollector* gc, bool only_marked = true);
    void gc_verify(memory::GarbageCollector* gc);
  };
}

#endif
<commit_msg>Slightly relax memory ordering for ThreadNexus::Phase.<commit_after>#ifndef RBX_VM_H
#define RBX_VM_H

#include "missing/time.h"

#include "globals.hpp"
#include "memory/object_mark.hpp"
#include "memory/managed.hpp"
#include "vm_thread_state.hpp"
#include "thread_nexus.hpp"
#include "metrics.hpp"

#include "util/thread.hpp"

#include "memory/variable_buffer.hpp"
#include "memory/root_buffer.hpp"
#include "memory/slab.hpp"

#include "shared_state.hpp"

#include "unwind_info.hpp"
#include "fiber_stack.hpp"

#include "sodium/randombytes.h"

#include <atomic>
#include <vector>
#include <setjmp.h>
#include <stdint.h>

namespace llvm {
  class Module;
}

namespace rbxti {
  class Env;
}

namespace rubinius {

  class Exception;
  class LLVMState;

  namespace event {
    class Loop;
  }

  namespace memory {
    class GarbageCollector;
    class WriteBarrier;
  }

  class Assertion;
  class CallSiteInformation;
  class Channel;
  class CompiledCode;
  class ConfigParser;
  class Configuration;
  class Fiber;
  class GlobalCache;
  class LookupTable;
  class Memory;
  class NativeMethodEnvironment;
  class Object;
  class Park;
  class Primitives;
  class SharedState;
  class String;
  class Symbol;
  class SymbolTable;
  class Tuple;
  class TypeError;
  class TypeInfo;
  class VariableScope;

  struct CallFrame;

  enum MethodMissingReason {
    eNone, ePrivate, eProtected, eSuper, eVCall, eNormal
  };

  enum ConstantMissingReason {
    vFound, vPrivate, vNonExistent
  };

  /**
   * Represents an execution context for running Ruby code.
   *
   * Each Ruby thread is backed by an instance of this class, as well as an
   * instance of the Thread class. Thread manages the (Ruby visible) thread-
   * related state, while this class manages the execution machinery for
   * running Ruby code.
   */

  class VM : public memory::ManagedThread {
    friend class State;

  private:
    UnwindInfoSet unwinds_;

    CallFrame* call_frame_;
    ThreadNexus* thread_nexus_;
    CallSiteInformation* saved_call_site_information_;
    FiberStacks fiber_stacks_;
    Park* park_;

    void* stack_start_;
    size_t stack_size_;
    size_t stack_cushion_;

    void* current_stack_start_;
    size_t current_stack_size_;

    bool interrupt_with_signal_;
    bool interrupt_by_kill_;
    bool check_local_interrupts_;
    bool thread_step_;

    utilities::thread::SpinLock interrupt_lock_;

    MethodMissingReason method_missing_reason_;
    ConstantMissingReason constant_missing_reason_;

    bool zombie_;
    bool allocation_tracking_;
    bool main_thread_;

    std::atomic<ThreadNexus::Phase> thread_phase_;

    uint32_t profile_interval_;
    uint32_t profile_counter_;
    CompiledCode** profile_;
    uint64_t profile_sample_count_;
    uint64_t profile_report_interval_;
    native_int max_profile_entries_;
    native_int min_profile_sample_count_;

  public:
    /* Data members */
    SharedState& shared;
    memory::TypedRoot<Channel*> waiting_channel_;
    memory::TypedRoot<Exception*> interrupted_exception_;
    /// The Thread object for this VM state
    memory::TypedRoot<Thread*> thread;

    /// The current fiber running on this thread
    memory::TypedRoot<Fiber*> current_fiber;

    /// Root fiber, if any (lazily initialized)
    memory::TypedRoot<Fiber*> root_fiber;

    /// Object that waits for inflation
    memory::TypedRoot<Object*> waiting_object_;

    uint64_t start_time_;

    NativeMethodEnvironment* native_method_environment;

    void (*custom_wakeup_)(void*);
    void* custom_wakeup_data_;

    VMThreadState thread_state_;

  public: /* Inline methods */

    UnwindInfoSet& unwinds() {
      return unwinds_;
    }

    uint32_t thread_id() const {
      return id_;
    }

    ThreadNexus* thread_nexus() {
      return thread_nexus_;
    }

    ThreadNexus::Phase thread_phase() {
      return thread_phase_.load(std::memory_order_acquire);
    }

    void set_thread_phase(ThreadNexus::Phase thread_phase) {
      thread_phase_.store(thread_phase, std::memory_order_release);
    }

    utilities::thread::SpinLock& interrupt_lock() {
      return interrupt_lock_;
    }

    void set_zombie(STATE);

    bool zombie_p() {
      return zombie_;
    }

    void set_main_thread() {
      main_thread_ = true;
    }

    bool main_thread_p() {
      return main_thread_;
    }

    VMThreadState* thread_state() {
      return &thread_state_;
    }

    Memory* memory() {
      return shared.memory();
    }

    void set_start_time();
    double run_time();

    void raise_stack_error(STATE);
    void validate_stack_size(STATE, size_t size);

    size_t stack_size() {
      return current_stack_size_;
    }

    void restore_stack_bounds() {
      current_stack_start_ = stack_start_;
      current_stack_size_ = stack_size_;
    }

    void set_stack_bounds(void* start, size_t size) {
      current_stack_start_ = start;
      current_stack_size_ = size - stack_cushion_;
    }

    void set_stack_bounds(size_t size);

    bool check_stack(STATE, void* stack_address) {
      ssize_t stack_used =
        (reinterpret_cast<intptr_t>(current_stack_start_)
        - reinterpret_cast<intptr_t>(stack_address));

      if(stack_used < 0) stack_used = -stack_used;

      if(static_cast<size_t>(stack_used) > current_stack_size_) {
        raise_stack_error(state);
        return false;
      }

      return true;
    }

    bool push_call_frame(STATE, CallFrame* frame, CallFrame*& previous_frame);

    bool pop_call_frame(STATE, CallFrame* frame) {
      call_frame_ = frame;

      return !thread_interrupted_p(state);
    }

    bool thread_interrupted_p(STATE) {
      if(check_local_interrupts()) {
        return check_thread_raise_or_kill(state);
      }

      return false;
    }

    bool check_thread_raise_or_kill(STATE);

    // Do NOT de-duplicate
    void set_call_frame(CallFrame* frame) {
      call_frame_ = frame;
    }

    CallFrame* call_frame() {
      return call_frame_;
    }

    CallFrame* get_call_frame(ssize_t up=0);
    CallFrame* get_ruby_frame(ssize_t up=0);
    CallFrame* get_variables_frame(ssize_t up=0);
    CallFrame* get_scope_frame(ssize_t up=0);

    bool scope_valid_p(VariableScope* scope);

    void set_call_site_information(CallSiteInformation* info) {
      saved_call_site_information_ = info;
    }

    CallSiteInformation* saved_call_site_information() {
      return saved_call_site_information_;
    }

    GlobalCache* global_cache() const {
      return shared.global_cache;
    }

    Globals& globals() {
      return shared.globals;
    }

    MethodMissingReason method_missing_reason() const {
      return method_missing_reason_;
    }

    void set_method_missing_reason(MethodMissingReason reason) {
      method_missing_reason_ = reason;
    }

    ConstantMissingReason constant_missing_reason() const {
      return constant_missing_reason_;
    }

    void set_constant_missing_reason(ConstantMissingReason reason) {
      constant_missing_reason_ = reason;
    }

    void after_fork_child(STATE);

    bool thread_step() const {
      return thread_step_;
    }

    void clear_thread_step() {
      clear_check_local_interrupts();
      thread_step_ = false;
    }

    void set_thread_step() {
      set_check_local_interrupts();
      thread_step_ = true;
    }

    bool check_local_interrupts() const {
      return check_local_interrupts_;
    }

    void clear_check_local_interrupts() {
      check_local_interrupts_ = false;
    }

    void set_check_local_interrupts() {
      check_local_interrupts_ = true;
    }

    bool interrupt_by_kill() const {
      return interrupt_by_kill_;
    }

    void clear_interrupt_by_kill() {
      interrupt_by_kill_ = false;
    }

    void set_interrupt_by_kill() {
      interrupt_by_kill_ = true;
    }

    Exception* interrupted_exception() const {
      return interrupted_exception_.get();
    }

    void clear_interrupted_exception() {
      interrupted_exception_.set(cNil);
    }

    bool allocation_tracking() const {
      return allocation_tracking_;
    }

    void enable_allocation_tracking() {
      allocation_tracking_ = true;
    }

    void disable_allocation_tracking() {
      allocation_tracking_ = false;
    }

    FiberStack* allocate_fiber_stack(size_t stack_size) {
      return fiber_stacks_.allocate(stack_size);
    }

    void* fiber_trampoline() {
      return fiber_stacks_.trampoline();
    }

    FiberData* new_fiber_data(size_t stack_size, bool root=false) {
      return fiber_stacks_.new_data(stack_size, root);
    }

    void remove_fiber_data(FiberData* data) {
      fiber_stacks_.remove_data(data);
    }

    memory::VariableRootBuffers& current_root_buffers();

  public:
    static VM* current();

    static void discard(STATE, VM*);

  public:

    /* Prototypes */
    VM(uint32_t id, SharedState& shared, const char* name = NULL);
    ~VM();

    void bootstrap_class(STATE);
    void bootstrap_ontology(STATE);
    void bootstrap_symbol(STATE);

    void collect_maybe(STATE);

    native_int max_profile_entries() {
      return max_profile_entries_;
    }

    uint64_t profile_sample_count() {
      return profile_sample_count_;
    }

    CompiledCode** profile() {
      return profile_;
    }

    void update_profile(STATE);
    void sort_profile();

#define RBX_PROFILE_MAX_SHIFT     0xf
#define RBX_PROFILE_MAX_INTERVAL  0x1fff

    void set_profile_interval() {
      profile_interval_ = randombytes_random();
      profile_interval_ >>= (profile_interval_ & RBX_PROFILE_MAX_SHIFT);
      profile_interval_ &= RBX_PROFILE_MAX_INTERVAL;
      profile_counter_ = 0;
    }

    void checkpoint(STATE) {
      metrics().machine.checkpoints++;

      if(thread_nexus_->try_lock(this)) {
        metrics().machine.stops++;

        collect_maybe(state);

        thread_nexus_->unlock();
      }

      if(profile_counter_++ >= profile_interval_) {
        update_profile(state);
        set_profile_interval();
      }
    }

    void blocking_suspend(STATE, metrics::metric& counter);
    void sleeping_suspend(STATE, metrics::metric& counter);

    void blocking_phase() {
      thread_nexus_->blocking_phase(this);
    }

    void managed_phase() {
      thread_nexus_->managed_phase(this);
    }

    void unmanaged_phase() {
      thread_nexus_->unmanaged_phase(this);
    }

    void set_current_thread();

    void setup_errno(STATE, int num, const char* name, Class* sce, Module* ern);
    void bootstrap_exceptions(STATE);
    void initialize_fundamental_constants(STATE);
    void initialize_builtin_classes(STATE);
    void initialize_platform_data(STATE);
    Object* ruby_lib_version();

    void set_current_fiber(Fiber* fib);

    TypeInfo* find_type(int type);

    static void init_ffi(STATE);

    void raise_from_errno(const char* reason);
    void raise_exception(Exception* exc);
    Exception* new_exception(Class* cls, const char* msg);
    Object* current_block();

    void set_const(const char* name, Object* val);
    void set_const(Module* mod, const char* name, Object* val);

    Object* path2class(const char* name);

    llvm::Module* llvm_module();
    void llvm_cleanup();

    void print_backtrace();

    void wait_on_channel(Channel* channel);
    void wait_on_inflated_lock(Object* wait);
    void wait_on_custom_function(void (*func)(void*), void* data);
    void clear_waiter();
    bool wakeup(STATE);

    void reset_parked();

    void set_sleeping();
    void clear_sleeping();

    void interrupt_with_signal() {
      interrupt_with_signal_ = true;
    }

    void register_raise(STATE, Exception* exc);
    void register_kill(STATE);

    void gc_scan(memory::GarbageCollector* gc);
    void gc_fiber_clear_mark();
    void gc_fiber_scan(memory::GarbageCollector* gc, bool only_marked = true);
    void gc_verify(memory::GarbageCollector* gc);
  };
}

#endif
<|endoftext|>


<commit_before>#ifndef HEAPS_H
#define HEAPS_H

#include"objects.hpp"

class Generic;
class SharedVar;

/*-----------------------------------------------------------------------------
Semispaces
-----------------------------------------------------------------------------*/

class Semispace {
private:
	void* mem;
	void* allocpt;
	void* svallocpt; // sharedvar allocation point
	size_t prev_alloc;
	size_t max;
public:
	Semispace(size_t);
	~Semispace();
	void* alloc(size_t);
	void dealloc(void*);
	SharedVar* sv_alloc(void);
	void sv_dealloc(SharedVar*);
	void resize(size_t);
	bool can_fit(size_t) const;

	size_t size(void) const { return max; };
	size_t used(void) const {
		return (size_t)(((char*) allocpt) - ((char*) mem))
			+ (size_t)((((char*) mem) + max) - ((char*) svallocpt));
	};

	std::pair<boost::shared_ptr<Semispace>, Generic* >
		clone(Generic*) const;

	friend class Heap;
};

/*last-in-first-out allocation semispace*/
class LifoSemispace {
private:
	void* mem;
	void* allocpt;
	void* end;
	size_t prevalloc;
public:
	LifoSemispace(size_t sz);
	~LifoSemispace();
	void* alloc(size_t sz);
	void dealloc(void*); // used only in a constructor-fail delete
	void normal_dealloc(Generic*);
	bool can_fit(size_t) const;
	size_t size(void) const {
		return (size_t) (((char*) end) - ((char*) mem));
	}
	size_t used(void) const {
		return (size_t) (((char*) end) - ((char*) allocpt));
	}
	/*no need to clone LIFO semispaces: they never get passed around*/

	friend class Heap;
};

#endif //HEAPS_H

<commit_msg>inc/heaps.hpp: minor comment<commit_after>#ifndef HEAPS_H
#define HEAPS_H

#include"objects.hpp"

class Generic;
class SharedVar;

/*-----------------------------------------------------------------------------
Semispaces
-----------------------------------------------------------------------------*/

class Semispace {
private:
	void* mem;
	void* allocpt;
	void* svallocpt; // sharedvar allocation point
	size_t prev_alloc;
	size_t max;
public:
	Semispace(size_t);
	~Semispace();
	void* alloc(size_t);
	void dealloc(void*);
	SharedVar* sv_alloc(void);
	void sv_dealloc(SharedVar*);
	void resize(size_t);
	bool can_fit(size_t) const;

	size_t size(void) const { return max; };
	size_t used(void) const {
		return (size_t)(((char*) allocpt) - ((char*) mem))
			+ (size_t)((((char*) mem) + max) - ((char*) svallocpt));
	};

	std::pair<boost::shared_ptr<Semispace>, Generic* >
		clone(Generic*) const;

	friend class Heap;
};

/*last-in-first-out allocation semispace*/
class LifoSemispace {
private:
	void* mem;
	void* allocpt;
	void* end;
	size_t prevalloc;
public:
	LifoSemispace(size_t sz);
	~LifoSemispace();
	void* alloc(size_t sz);
	void dealloc(void*); // used only in a constructor-fail delete
	void normal_dealloc(Generic*);
	/*no svallocation: no sharedvar's allowed in LifoSemispace*/

	bool can_fit(size_t) const;
	size_t size(void) const {
		return (size_t) (((char*) end) - ((char*) mem));
	}
	size_t used(void) const {
		return (size_t) (((char*) end) - ((char*) allocpt));
	}
	/*no need to clone LIFO semispaces: they never get passed around*/

	friend class Heap;
};

#endif //HEAPS_H

<|endoftext|>


<commit_before>#include "persons.h"
#include <iomanip>

//Default Constructor.
//Not actually used.
Persons::Persons()
{
    name = " ";
    gender = ' ';
    birthYear = 1980;
    deathYear = 0;
    alive = true;
}

//Constructor.
//if deathyear == 0, the person will be alive.
Persons::Persons(string n, char g, int bY, int dY)
{
    name = n;
    birthYear = bY;
    deathYear = dY;
    gender = g;
    if (dY == 0)
    {
        alive = true;
    }
    else
    {
        alive = false;
    }
}

string Persons::getName() const
{
    return name;
}

int Persons::getBirthYear() const
{
    return birthYear;
}

int Persons::getDeathYear() const
{
    return deathYear;
}

char Persons::getGender() const
{
    return gender;
}

bool Persons::getAlive() const
{
    return alive;
}

//Overloads the = operator. Basic stuff.
void Persons::operator = (const Persons& p)
{
    name = p.name;
    gender = p.gender;
    birthYear = p.birthYear;
    deathYear = p.deathYear;
    alive = p.alive;
}

//Overloads the == operator.
//Two persons are equal if and only if each
//Parameter is equal.
bool Persons::operator == (const Persons& p)
{
    return name == p.name && gender == p.gender && birthYear == p.birthYear && deathYear == p.deathYear;
}

//Overloads the << (output) operator.
//writes out the name, gender, and birthyear.
//Writes out the deathyear or, if the person is alive
//writes "Alive".
ostream& operator << (ostream& out, const Persons& p)
{
    out.width(26);
    out << left << p.getName() << "\t" <<  p.getGender() << "\t" << p.getBirthYear() << "\t";
    if (!p.getAlive())
    {
        out << p.getDeathYear() << endl;
    }
    else
    {
        out << "Alive " << endl;
    }
    return out;
}

//Overloads the >> (input) operator.
//Reads the name which we know ends at a ;
//Then reads the gender and birthyear.
//Reads either "Alive" or the deathyear.
istream& operator >> (istream& in, Persons& p)
{
    string a = " ";
    in >> ws;
    getline(in, p.name, ';');
    in >> p.gender >> p.birthYear >> a;
    if (a == "Alive")
    {
        p.alive = true;
    }
    else
    {
        p.alive = false;
        p.deathYear = atoi(a.c_str());
    }
    return in;
}
<commit_msg>sortByDeathYear lagað<commit_after>#include "persons.h"
#include <iomanip>

//Default Constructor.
//Not actually used.
Persons::Persons()
{
    name = " ";
    gender = ' ';
    birthYear = 1980;
    deathYear = 0;
    alive = true;
}

//Constructor.
//if deathyear == 0, the person will be alive.
Persons::Persons(string n, char g, int bY, int dY)
{
    name = n;
    birthYear = bY;
    deathYear = dY;
    gender = g;
    if (dY == 0)
    {
        alive = true;
    }
    else
    {
        alive = false;
    }
}

string Persons::getName() const
{
    return name;
}

int Persons::getBirthYear() const
{
    return birthYear;
}

int Persons::getDeathYear() const
{
    return deathYear;
}

char Persons::getGender() const
{
    return gender;
}

bool Persons::getAlive() const
{
    return alive;
}

//Overloads the = operator. Basic stuff.
void Persons::operator = (const Persons& p)
{
    name = p.name;
    gender = p.gender;
    birthYear = p.birthYear;
    deathYear = p.deathYear;
    alive = p.alive;
}

//Overloads the == operator.
//Two persons are equal if and only if each
//Parameter is equal.
bool Persons::operator == (const Persons& p)
{
    return name == p.name && gender == p.gender && birthYear == p.birthYear && deathYear == p.deathYear;
}

//Overloads the << (output) operator.
//writes out the name, gender, and birthyear.
//Writes out the deathyear or, if the person is alive
//writes "Alive".
ostream& operator << (ostream& out, const Persons& p)
{
    out.width(26);
    out << left << p.getName() << "\t" <<  p.getGender() << "\t" << p.getBirthYear() << "\t";
    if (!p.getAlive())
    {
        out << p.getDeathYear() << endl;
    }
    else
    {
        out << "Alive " << endl;
    }
    return out;
}

//Overloads the >> (input) operator.
//Reads the name which we know ends at a ;
//Then reads the gender and birthyear.
//Reads either "Alive" or the deathyear.
istream& operator >> (istream& in, Persons& p)
{
    string a = " ";
    in >> ws;
    getline(in, p.name, ';');
    in >> p.gender >> p.birthYear >> a;
    if (a == "Alive")
    {
        p.alive = true;
        p.deathYear = 0;
    }
    else
    {
        p.alive = false;
        p.deathYear = atoi(a.c_str());
    }
    return in;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: docprev.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-12 14:59:03 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SFX_OBJSH_HXX // SfxObjectShell
#include <sfx2/objsh.hxx>
#endif

#ifndef _SV_GDIMTF_HXX // GDIMetaFile
#include <vcl/gdimtf.hxx>
#endif

#ifndef _SV_VIRDEV_HXX // class VirtualDevice
#include <vcl/virdev.hxx>
#endif

#ifndef _COM_SUN_STAR_PRESENTATION_FADEEFFECT_HPP_
#include <com/sun/star/presentation/FadeEffect.hpp>
#endif

#ifndef _SD_FADEDEF_H // enum FadeSpeed
#include <fadedef.h>
#endif

#ifndef _SV_CTRL_HXX // class Control
#include <vcl/ctrl.hxx>
#endif

#ifndef _SVDOUTL_HXX
#include <svx/svdoutl.hxx>
#endif
#ifndef _SVDPAGV_HXX
#include <svx/svdpagv.hxx>
#endif
#ifndef _SVDORECT_HXX
#include <svx/svdorect.hxx>
#endif

#ifndef SD_FADER_HXX
#include "fader.hxx"
#endif

#include "docprev.hxx"
#include "drawdoc.hxx"
#include "DrawDocShell.hxx"
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_SHOW_VIEW_HXX
#include "showview.hxx"
#endif
#ifndef SD_DRAW_VIEW_HXX
#include "drawview.hxx"
#endif
#include "sdpage.hxx"

using namespace ::com::sun::star;

const int SdDocPreviewWin::FRAME = 4;

void SdDocPreviewWin::SetObjectShell( SfxObjectShell* pObj, sal_uInt16 nShowPage )
{
    mpObj = pObj;
    mnShowPage = nShowPage;

    updateViewSettings();
}

SdDocPreviewWin::SdDocPreviewWin( Window* pParent, const ResId& rResId )
: Control(pParent, rResId), pMetaFile( 0 ), bInEffect(FALSE), mpObj(NULL), mnShowPage(0)
{
    SetBorderStyle( WINDOW_BORDER_MONO );
    svtools::ColorConfig aColorConfig;
    SetBackground( Wallpaper( Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor ) ) );
}

SdDocPreviewWin::SdDocPreviewWin( Window* pParent )
: Control(pParent, 0 ), pMetaFile( 0 ), bInEffect(FALSE), mpObj(NULL), mnShowPage(0)
{
    SetBorderStyle( WINDOW_BORDER_MONO );
    svtools::ColorConfig aColorConfig;
    SetBackground( Wallpaper( Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor ) ) );
    Resize();
    Show();
}

void SdDocPreviewWin::Resize()
{
    Invalidate();
}

void SdDocPreviewWin::SetGDIFile( GDIMetaFile* pFile )
{
    delete pMetaFile;
    pMetaFile = pFile;
    Invalidate();
}

void SdDocPreviewWin::CalcSizeAndPos( GDIMetaFile* pFile, Size& rSize, Point& rPoint )
{
    Size aTmpSize = pFile ? pFile->GetPrefSize() : Size(1,1 );
    long nWidth = rSize.Width() - 2*FRAME;
    long nHeight = rSize.Height() - 2*FRAME;
    if( nWidth < 0 ) nWidth = 0;
    if( nHeight < 0 ) nHeight = 0;

    double dRatio=((double)aTmpSize.Width())/aTmpSize.Height();
    double dRatioPreV=((double) nWidth ) / nHeight;

    if (dRatio>dRatioPreV)
    {
        rSize=Size(nWidth, (USHORT)(nWidth/dRatio));
        rPoint=Point( 0, (USHORT)((nHeight-rSize.Height())/2));
    }
    else
    {
        rSize=Size((USHORT)(nHeight*dRatio), nHeight);
        rPoint=Point((USHORT)((nWidth-rSize.Width())/2),0);
    }
}

void SdDocPreviewWin::ImpPaint( GDIMetaFile* pFile, OutputDevice* pVDev )
{
    Point aPoint;
    Size aSize = pVDev->GetOutputSize();
    Point bPoint(aSize.Width()-2*FRAME, aSize.Height()-2*FRAME );
    CalcSizeAndPos( pFile, aSize, aPoint );
    bPoint -= aPoint;
    aPoint += Point( FRAME, FRAME );

    svtools::ColorConfig aColorConfig;

    pVDev->SetLineColor();
    pVDev->SetFillColor( Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor ) );
    pVDev->DrawRect(Rectangle( Point(0,0 ), pVDev->GetOutputSize()));
    if( pFile )
    {
        pVDev->SetFillColor( maDocumentColor );
        pVDev->DrawRect(Rectangle(aPoint, aSize));
        pFile->WindStart();
        pFile->Play( pVDev, aPoint, aSize  );
    }
}

void SdDocPreviewWin::Paint( const Rectangle& rRect )
{
    SvtAccessibilityOptions aAccOptions;
    bool bUseContrast = aAccOptions.GetIsForPagePreviews() && Application::GetSettings().GetStyleSettings().GetHighContrastMode();
    SetDrawMode( bUseContrast
        ? ::sd::ViewShell::OUTPUT_DRAWMODE_CONTRAST
        : ::sd::ViewShell::OUTPUT_DRAWMODE_COLOR );

    ImpPaint( pMetaFile, (VirtualDevice*)this );
}

void SdDocPreviewWin::ShowEffect( presentation::FadeEffect eEffect, FadeSpeed eSpeed )
{
    if(bInEffect || !pMetaFile)
        return;

    bInEffect = TRUE;

    svtools::ColorConfig aColorConfig;

    SetLineColor();
    SetFillColor( Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor ) );
    DrawRect(Rectangle( Point(0,0 ), GetOutputSize()));

    Point aPoint;
    Size aSize( GetOutputSize() );
    Point bPoint(aSize.Width()-2*FRAME, aSize.Height()-2*FRAME );
    CalcSizeAndPos( pMetaFile, aSize, aPoint );
    bPoint -= aPoint;
    aPoint += Point( FRAME, FRAME );

    // virtuelle Devices anlegen

    VirtualDevice* pVDev = new VirtualDevice(*this);
    pVDev->SetOutputSize( GetOutputSize() );
    pVDev->SetFillColor( maDocumentColor );
    pVDev->DrawRect(Rectangle(aPoint, aSize));

    pVDev->SetLineColor();
    pVDev->SetFillColor( Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor ) );
    pVDev->DrawRect(Rectangle( Point(0,0 ), pVDev->GetOutputSize()));
    if( pMetaFile )
    {
        pVDev->SetFillColor( maDocumentColor );
        pVDev->DrawRect(Rectangle(aPoint, aSize));
        pMetaFile->WindStart();
        pMetaFile->Play( pVDev, aPoint, aSize  );
    }

    // ein Fader zum Ueberblenden
    ::sd::Fader* pFader = new ::sd::Fader(this);
    pFader->SetEffect( eEffect );
    pFader->SetSpeed( eSpeed );
    pFader->SetSource(Rectangle(aPoint, aSize));
    pFader->SetTarget(Rectangle(aPoint, aSize));

    // virtuelle Devices an Fader uebergeben
    pFader->SetNewVirtualDevice(pVDev);

    // ueberblenden
    pFader->Fade();

    delete pFader;

//  DrawOutDev( Point( 0,0 ), GetOutputSize(), Point( 0,0 ), GetOutputSize(), *pVDev );

    delete pVDev;

/*
    Point aPoint;
    Size aSize = GetOutputSize();
    Point bPoint( aSize.Width() - 2*FRAME, aSize.Height() - 2*FRAME );
    CalcSizeAndPos( pMetaFile, aSize, aPoint );
    bPoint -= aPoint;

    aPoint += Point( FRAME, FRAME );
    bPoint += Point( FRAME, FRAME );

    svtools::ColorConfig aColorConfig;

    // Hintergrund Schwarz
    SetLineColor();
    SetFillColor( Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor ) );
    DrawRect(Rectangle( Point(0,0 ), GetOutputSize()));

    // korrigierte Seitengroesse, sonst kommt die letzte Pixelreihe(spalte)
    // nicht mit
    Size aPixelSize = PixelToLogic(Size(1,1));
    aSize.Width()   += aPixelSize.Width();
    aSize.Height() += aPixelSize.Height();

*/

    bInEffect = FALSE;
}

long SdDocPreviewWin::Notify( NotifyEvent& rNEvt )
{
    if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
    {
        const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
        if ( pMEvt->IsLeft() )
        {
            if( rNEvt.GetWindow() == this )
            {
                if(aClickHdl.IsSet())
                    aClickHdl.Call(this);
            }
        }
    }

    return Control::Notify( rNEvt );
}

void SdDocPreviewWin::updateViewSettings()
{
    ::sd::DrawDocShell* pDocShell = PTR_CAST(::sd::DrawDocShell,mpObj);
    SdDrawDocument* pDoc = pDocShell?pDocShell->GetDoc():NULL;

    SvtAccessibilityOptions aAccOptions;
    bool bUseWhiteColor = !aAccOptions.GetIsForPagePreviews() && GetSettings().GetStyleSettings().GetHighContrastMode();
    if( bUseWhiteColor )
    {
        maDocumentColor = Color( COL_WHITE );
    }
    else
    {
        svtools::ColorConfig aColorConfig;
        maDocumentColor = Color( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
    }

    GDIMetaFile* pMtf = NULL;

    if(pDoc)
    {
        SdrOutliner& rOutl = pDoc->GetDrawOutliner();
        Color aOldBackgroundColor = rOutl.GetBackgroundColor();
        rOutl.SetBackgroundColor( maDocumentColor );

        pMtf = new GDIMetaFile;
        SdPage * pPage = pDoc->GetSdPage( mnShowPage, PK_STANDARD );

        VirtualDevice       aVDev;

        const Fraction      aFrac( pDoc->GetScaleFraction() );
        const MapMode       aMap( pDoc->GetScaleUnit(), Point(), aFrac, aFrac );

        aVDev.SetMapMode( aMap );

        // #109058# Disable output, as we only want to record a metafile
        aVDev.EnableOutput( FALSE );

        pMtf->Record( &aVDev );

        ::sd::DrawView* pView = new ::sd::DrawView(pDocShell, this, NULL);

        const Size aSize( pPage->GetSize() );

        pView->SetBordVisible( FALSE );
        pView->SetPageVisible( FALSE );
        pView->ShowPage( pPage, Point() );

        const Point aNewOrg( pPage->GetLftBorder(), pPage->GetUppBorder() );
        const Size aNewSize( aSize.Width() - pPage->GetLftBorder() - pPage->GetRgtBorder(),
                              aSize.Height() - pPage->GetUppBorder() - pPage->GetLwrBorder() );
        const Rectangle aClipRect( aNewOrg, aNewSize );
        MapMode         aVMap( aMap );

        SdrPageView* pPageView  = pView->GetPageView( pPage );

        aVDev.Push();
        aVMap.SetOrigin( Point( -aNewOrg.X(), -aNewOrg.Y() ) );
        aVDev.SetRelativeMapMode( aVMap );
        aVDev.IntersectClipRegion( aClipRect );

        // Use new StandardCheckVisisbilityRedirector
        StandardCheckVisisbilityRedirector aRedirector;

        for (USHORT i=0; i<pView->GetPageViewCount(); i++)
        {
            SdrPageView* pPV=pView->GetPageViewPvNum(i);
            pPV->CompleteRedraw(&aVDev, Region(Rectangle(Point(), aNewSize)), 0, &aRedirector);
        }

        aVDev.Pop();

        pMtf->Stop();
        pMtf->WindStart();
        pMtf->SetPrefMapMode( aMap );
        pMtf->SetPrefSize( aNewSize );

        rOutl.SetBackgroundColor( aOldBackgroundColor );

        delete pView;
    }

    delete pMetaFile;
    pMetaFile = pMtf;

    Invalidate();
}

void SdDocPreviewWin::SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType, const SfxHint& rHint, const TypeId& rHintType)
{
    if( rHint.ISA( SfxSimpleHint ) && ( (SfxSimpleHint&) rHint ).GetId() == SFX_HINT_COLORS_CHANGED )
    {
        updateViewSettings();
    }
}
void SdDocPreviewWin::DataChanged( const DataChangedEvent& rDCEvt )
{
    Control::DataChanged( rDCEvt );

    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        updateViewSettings();
    }
}
<commit_msg>INTEGRATION: CWS presentationengine01 (1.12.12); FILE MERGED 2004/09/30 16:09:40 cl 1.12.12.2: added new preview for wizard 2004/08/25 15:24:04 cl 1.12.12.1: replaced old FuSlideShow with new SlideShow<commit_after>/*************************************************************************
 *
 *  $RCSfile: docprev.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-26 20:02:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_DRAWING_XDRAWPAGE_HPP_
#include <com/sun/star/drawing/XDrawPage.hpp>
#endif
#ifndef _COM_SUN_STAR_ANIMATIONS_XANIMATIONNODE_HPP_
#include <com/sun/star/animations/XAnimationNode.hpp>
#endif

#ifndef _SD_SLIDESHOW_HXX
#include "slideshow.hxx"
#endif

#ifndef _SFX_OBJSH_HXX // SfxObjectShell
#include <sfx2/objsh.hxx>
#endif

#ifndef _SV_GDIMTF_HXX // GDIMetaFile
#include <vcl/gdimtf.hxx>
#endif

#ifndef _SV_VIRDEV_HXX // class VirtualDevice
#include <vcl/virdev.hxx>
#endif

#ifndef _COM_SUN_STAR_PRESENTATION_FADEEFFECT_HPP_
#include <com/sun/star/presentation/FadeEffect.hpp>
#endif

#ifndef _SD_FADEDEF_H // enum FadeSpeed
#include <fadedef.h>
#endif

#ifndef _SV_CTRL_HXX // class Control
#include <vcl/ctrl.hxx>
#endif

#ifndef _SVDOUTL_HXX
#include <svx/svdoutl.hxx>
#endif
#ifndef _SVDPAGV_HXX
#include <svx/svdpagv.hxx>
#endif
#ifndef _SVDORECT_HXX
#include <svx/svdorect.hxx>
#endif

#include "docprev.hxx"
#include "drawdoc.hxx"
#include "DrawDocShell.hxx"
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_SHOW_VIEW_HXX
#include "showview.hxx"
#endif
#ifndef SD_DRAW_VIEW_HXX
#include "drawview.hxx"
#endif
#include "sdpage.hxx"

using ::com::sun::star::drawing::XDrawPage;
using ::com::sun::star::animations::XAnimationNode;

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

const int SdDocPreviewWin::FRAME = 4;

void SdDocPreviewWin::SetObjectShell( SfxObjectShell* pObj, sal_uInt16 nShowPage )
{
    mpObj = pObj;
    mnShowPage = nShowPage;
    delete mpSlideShow;
    mpSlideShow = 0;

    updateViewSettings();
}

SdDocPreviewWin::SdDocPreviewWin( Window* pParent, const ResId& rResId )
: Control(pParent, rResId), pMetaFile( 0 ), bInEffect(FALSE), mpObj(NULL), mnShowPage(0)
{
    mpSlideShow = 0;
    SetBorderStyle( WINDOW_BORDER_MONO );
    svtools::ColorConfig aColorConfig;
    SetBackground( Wallpaper( Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor ) ) );
}

SdDocPreviewWin::SdDocPreviewWin( Window* pParent )
: Control(pParent, 0 ), pMetaFile( 0 ), bInEffect(FALSE), mpObj(NULL), mnShowPage(0)
{
    mpSlideShow = 0;
    SetBorderStyle( WINDOW_BORDER_MONO );
    svtools::ColorConfig aColorConfig;
    SetBackground( Wallpaper( Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor ) ) );
    Resize();
    Show();
}

void SdDocPreviewWin::Resize()
{
    Invalidate();
    if( mpSlideShow )
        mpSlideShow->resize( GetSizePixel() );
}

void SdDocPreviewWin::SetGDIFile( GDIMetaFile* pFile )
{
    delete pMetaFile;
    pMetaFile = pFile;
    Invalidate();
}

void SdDocPreviewWin::CalcSizeAndPos( GDIMetaFile* pFile, Size& rSize, Point& rPoint )
{
    Size aTmpSize = pFile ? pFile->GetPrefSize() : Size(1,1 );
    long nWidth = rSize.Width() - 2*FRAME;
    long nHeight = rSize.Height() - 2*FRAME;
    if( nWidth < 0 ) nWidth = 0;
    if( nHeight < 0 ) nHeight = 0;

    double dRatio=((double)aTmpSize.Width())/aTmpSize.Height();
    double dRatioPreV=((double) nWidth ) / nHeight;

    if (dRatio>dRatioPreV)
    {
        rSize=Size(nWidth, (USHORT)(nWidth/dRatio));
        rPoint=Point( 0, (USHORT)((nHeight-rSize.Height())/2));
    }
    else
    {
        rSize=Size((USHORT)(nHeight*dRatio), nHeight);
        rPoint=Point((USHORT)((nWidth-rSize.Width())/2),0);
    }
}

void SdDocPreviewWin::ImpPaint( GDIMetaFile* pFile, OutputDevice* pVDev )
{
    Point aPoint;
    Size aSize = pVDev->GetOutputSize();
    Point bPoint(aSize.Width()-2*FRAME, aSize.Height()-2*FRAME );
    CalcSizeAndPos( pFile, aSize, aPoint );
    bPoint -= aPoint;
    aPoint += Point( FRAME, FRAME );

    svtools::ColorConfig aColorConfig;

    pVDev->SetLineColor();
    pVDev->SetFillColor( Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor ) );
    pVDev->DrawRect(Rectangle( Point(0,0 ), pVDev->GetOutputSize()));
    if( pFile )
    {
        pVDev->SetFillColor( maDocumentColor );
        pVDev->DrawRect(Rectangle(aPoint, aSize));
        pFile->WindStart();
        pFile->Play( pVDev, aPoint, aSize  );
    }
}

void SdDocPreviewWin::Paint( const Rectangle& rRect )
{
    SvtAccessibilityOptions aAccOptions;
    bool bUseContrast = aAccOptions.GetIsForPagePreviews() && Application::GetSettings().GetStyleSettings().GetHighContrastMode();
    SetDrawMode( bUseContrast
        ? ::sd::ViewShell::OUTPUT_DRAWMODE_CONTRAST
        : ::sd::ViewShell::OUTPUT_DRAWMODE_COLOR );

    ImpPaint( pMetaFile, (VirtualDevice*)this );
}

void SdDocPreviewWin::startPreview()
{
    if( mpSlideShow )
        delete mpSlideShow;

    ::sd::DrawDocShell* pDocShell = dynamic_cast< ::sd::DrawDocShell * >( mpObj );
    if( mpObj )
    {
        SdDrawDocument* pDoc = pDocShell->GetDoc();

        if( pDoc )
        {
            SdPage* pPage = pDoc->GetSdPage( mnShowPage, PK_STANDARD );

            if( pPage )
            {
                mpSlideShow = new sd::Slideshow( 0, 0, pDoc );

                Reference< XDrawPage > xDrawPage( pPage->getUnoPage(), UNO_QUERY );
                Reference< XAnimationNode > xAnimationNode;

                mpSlideShow->startPreview( xDrawPage, xAnimationNode, this );
            }
        }
    }
}

long SdDocPreviewWin::Notify( NotifyEvent& rNEvt )
{
    if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
    {
        const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
        if ( pMEvt->IsLeft() )
        {
            if( rNEvt.GetWindow() == this )
            {
                if(aClickHdl.IsSet())
                    aClickHdl.Call(this);
            }
        }
    }

    return Control::Notify( rNEvt );
}

void SdDocPreviewWin::updateViewSettings()
{
    ::sd::DrawDocShell* pDocShell = PTR_CAST(::sd::DrawDocShell,mpObj);
    SdDrawDocument* pDoc = pDocShell?pDocShell->GetDoc():NULL;

    SvtAccessibilityOptions aAccOptions;
    bool bUseWhiteColor = !aAccOptions.GetIsForPagePreviews() && GetSettings().GetStyleSettings().GetHighContrastMode();
    if( bUseWhiteColor )
    {
        maDocumentColor = Color( COL_WHITE );
    }
    else
    {
        svtools::ColorConfig aColorConfig;
        maDocumentColor = Color( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
    }

    GDIMetaFile* pMtf = NULL;

    if(pDoc)
    {
        SdrOutliner& rOutl = pDoc->GetDrawOutliner();
        Color aOldBackgroundColor = rOutl.GetBackgroundColor();
        rOutl.SetBackgroundColor( maDocumentColor );

        pMtf = new GDIMetaFile;
        SdPage * pPage = pDoc->GetSdPage( mnShowPage, PK_STANDARD );

        VirtualDevice       aVDev;

        const Fraction      aFrac( pDoc->GetScaleFraction() );
        const MapMode       aMap( pDoc->GetScaleUnit(), Point(), aFrac, aFrac );

        aVDev.SetMapMode( aMap );

        // #109058# Disable output, as we only want to record a metafile
        aVDev.EnableOutput( FALSE );

        pMtf->Record( &aVDev );

        ::sd::DrawView* pView = new ::sd::DrawView(pDocShell, this, NULL);

        const Size aSize( pPage->GetSize() );

        pView->SetBordVisible( FALSE );
        pView->SetPageVisible( FALSE );
        pView->ShowPage( pPage, Point() );

        const Point aNewOrg( pPage->GetLftBorder(), pPage->GetUppBorder() );
        const Size aNewSize( aSize.Width() - pPage->GetLftBorder() - pPage->GetRgtBorder(),
                              aSize.Height() - pPage->GetUppBorder() - pPage->GetLwrBorder() );
        const Rectangle aClipRect( aNewOrg, aNewSize );
        MapMode         aVMap( aMap );

        SdrPageView* pPageView  = pView->GetPageView( pPage );

        aVDev.Push();
        aVMap.SetOrigin( Point( -aNewOrg.X(), -aNewOrg.Y() ) );
        aVDev.SetRelativeMapMode( aVMap );
        aVDev.IntersectClipRegion( aClipRect );

        // Use new StandardCheckVisisbilityRedirector
        StandardCheckVisisbilityRedirector aRedirector;

        for (USHORT i=0; i<pView->GetPageViewCount(); i++)
        {
            SdrPageView* pPV=pView->GetPageViewPvNum(i);
            pPV->CompleteRedraw(&aVDev, Region(Rectangle(Point(), aNewSize)), 0, &aRedirector);
        }

        aVDev.Pop();

        pMtf->Stop();
        pMtf->WindStart();
        pMtf->SetPrefMapMode( aMap );
        pMtf->SetPrefSize( aNewSize );

        rOutl.SetBackgroundColor( aOldBackgroundColor );

        delete pView;
    }

    delete pMetaFile;
    pMetaFile = pMtf;

    Invalidate();
}

void SdDocPreviewWin::SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType, const SfxHint& rHint, const TypeId& rHintType)
{
    if( rHint.ISA( SfxSimpleHint ) && ( (SfxSimpleHint&) rHint ).GetId() == SFX_HINT_COLORS_CHANGED )
    {
        updateViewSettings();
    }
}
void SdDocPreviewWin::DataChanged( const DataChangedEvent& rDCEvt )
{
    Control::DataChanged( rDCEvt );

    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        updateViewSettings();
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fuchar.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: ka $ $Date: 2000-09-21 16:11:55 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include <svx/editdata.hxx>
#include <svx/svxids.hrc>
#ifndef _EEITEM_HXX //autogen
#include <svx/eeitem.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFX_BINDINGS_HXX //autogen
#include <sfx2/bindings.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif

#include "dlg_char.hxx"
#include "sdview.hxx"
#include "drawview.hxx"
#include "drawdoc.hxx"
#include "drviewsh.hxx"
#include "viewshel.hxx"
#include "docshell.hxx"
#include "fuchar.hxx"

TYPEINIT1( FuChar, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuChar::FuChar(SdViewShell* pViewSh, SdWindow* pWin, SdView* pView,
                 SdDrawDocument* pDoc, SfxRequest& rReq)
       : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
{
    const SfxItemSet* pArgs = rReq.GetArgs();

    if( !pArgs )
    {
        SfxItemSet aEditAttr( pDoc->GetPool() );
        pView->GetAttributes( aEditAttr );

        SfxItemSet aNewAttr( pViewSh->GetPool(),
                                EE_ITEMS_START, EE_ITEMS_END );
        aNewAttr.Put( aEditAttr, FALSE );

        SdCharDlg* pDlg = new SdCharDlg( NULL, &aNewAttr, pDoc->GetDocSh() );

        USHORT nResult = pDlg->Execute();

        switch( nResult )
        {
            case RET_OK:
            {
                rReq.Done( *( pDlg->GetOutputItemSet() ) );

                pArgs = rReq.GetArgs();
            }
            break;

            default:
            {
                delete pDlg;
            }
            return; // Abbruch
        }
        delete( pDlg );
    }
    pView->SetAttributes(*pArgs);

    // invalidieren der Slots, die in der DrTxtObjBar auftauchen
    static USHORT SidArray[] = {
                    SID_ATTR_CHAR_FONT,
                    SID_ATTR_CHAR_POSTURE,
                    SID_ATTR_CHAR_WEIGHT,
                    SID_ATTR_CHAR_UNDERLINE,
                    SID_ATTR_CHAR_FONTHEIGHT,
                    SID_ATTR_CHAR_COLOR,
                    SID_SET_SUPER_SCRIPT,
                    SID_SET_SUB_SCRIPT,
                    0 };

    pViewShell->GetViewFrame()->GetBindings().Invalidate( SidArray );
}

<commit_msg>#94797# Start online spelling if language changed<commit_after>/*************************************************************************
 *
 *  $RCSfile: fuchar.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: dl $ $Date: 2001-11-16 10:03:51 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include <svx/editdata.hxx>
#include <svx/svxids.hrc>
#ifndef _EEITEM_HXX //autogen
#include <svx/eeitem.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFX_BINDINGS_HXX //autogen
#include <sfx2/bindings.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif

#include "dlg_char.hxx"
#include "sdview.hxx"
#include "drawview.hxx"
#include "drawdoc.hxx"
#include "drviewsh.hxx"
#include "viewshel.hxx"
#include "docshell.hxx"
#include "fuchar.hxx"

TYPEINIT1( FuChar, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuChar::FuChar(SdViewShell* pViewSh, SdWindow* pWin, SdView* pView,
                 SdDrawDocument* pDoc, SfxRequest& rReq)
       : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
{
    const SfxItemSet* pArgs = rReq.GetArgs();

    if( !pArgs )
    {
        SfxItemSet aEditAttr( pDoc->GetPool() );
        pView->GetAttributes( aEditAttr );

        SfxItemSet aNewAttr( pViewSh->GetPool(),
                                EE_ITEMS_START, EE_ITEMS_END );
        aNewAttr.Put( aEditAttr, FALSE );

        SdCharDlg* pDlg = new SdCharDlg( NULL, &aNewAttr, pDoc->GetDocSh() );

        USHORT nResult = pDlg->Execute();

        switch( nResult )
        {
            case RET_OK:
            {
                rReq.Done( *( pDlg->GetOutputItemSet() ) );

                pArgs = rReq.GetArgs();
            }
            break;

            default:
            {
                delete pDlg;
            }
            return; // Abbruch
        }
        delete( pDlg );
    }
    pView->SetAttributes(*pArgs);

    // invalidieren der Slots, die in der DrTxtObjBar auftauchen
    static USHORT SidArray[] = {
                    SID_ATTR_CHAR_FONT,
                    SID_ATTR_CHAR_POSTURE,
                    SID_ATTR_CHAR_WEIGHT,
                    SID_ATTR_CHAR_UNDERLINE,
                    SID_ATTR_CHAR_FONTHEIGHT,
                    SID_ATTR_CHAR_COLOR,
                    SID_SET_SUPER_SCRIPT,
                    SID_SET_SUB_SCRIPT,
                    0 };

    pViewShell->GetViewFrame()->GetBindings().Invalidate( SidArray );

    if( pDoc->GetOnlineSpell() )
    {
        const SfxPoolItem* pItem;
        if( SFX_ITEM_SET == pArgs->GetItemState(EE_CHAR_LANGUAGE, FALSE, &pItem ) ||
            SFX_ITEM_SET == pArgs->GetItemState(EE_CHAR_LANGUAGE_CJK, FALSE, &pItem ) ||
            SFX_ITEM_SET == pArgs->GetItemState(EE_CHAR_LANGUAGE_CTL, FALSE, &pItem ) )
        {
            pDoc->StopOnlineSpelling();
            pDoc->StartOnlineSpelling();
        }
    }
}

<|endoftext|>


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

#include "fuvect.hxx"

#ifndef _TL_POLY_HXX
#include <tools/poly.hxx>
#endif
#ifndef _SVDOPATH_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SVX_SVDOGRAF_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SVX_SVDEDTV_HXX //autogen
#include <svx/svdedtv.hxx>
#endif

#pragma hdrstop

#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#include "strings.hrc"
#include "sdresid.hxx"
//CHINA001 #include "vectdlg.hxx"
#include "sdabstdlg.hxx" //CHINA001
#include "vectdlg.hrc" //CHINA001
namespace sd {

TYPEINIT1( FuVectorize, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuVectorize::FuVectorize (
    ViewShell* pViewSh,
    ::sd::Window* pWin,
    ::sd::View* pView,
    SdDrawDocument* pDoc,
    SfxRequest& rReq)
    : FuPoor (pViewSh, pWin, pView, pDoc, rReq)
{
}

FunctionReference FuVectorize::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
{
    FunctionReference xFunc( new FuVectorize( pViewSh, pWin, pView, pDoc, rReq ) );
    xFunc->DoExecute(rReq);
    return xFunc;
}

void FuVectorize::DoExecute( SfxRequest& rReq )
{
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetObj();

        if( pObj && pObj->ISA( SdrGrafObj ) )
        {
            SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
            AbstractSdVectorizeDlg* pDlg = pFact ? pFact->CreateSdVectorizeDlg(ResId( DLG_VECTORIZE ), pWindow, ( (SdrGrafObj*) pObj )->GetGraphic().GetBitmap(), pDocSh ) : 0;
            DBG_ASSERT(pDlg, "Dialogdiet fail!");
            if( pDlg && pDlg->Execute() == RET_OK )
            {
                const GDIMetaFile&  rMtf = pDlg->GetGDIMetaFile(); //CHINA001 const GDIMetaFile&    rMtf = aDlg.GetGDIMetaFile();
                SdrPageView*        pPageView = pView->GetPageViewPvNum( 0 );

                if( pPageView && rMtf.GetActionCount() )
                {
                    SdrGrafObj* pVectObj = (SdrGrafObj*) pObj->Clone();
                    String      aStr( pView->GetDescriptionOfMarkedObjects() );

                    aStr.Append( sal_Unicode(' ') );
                    aStr.Append( String( SdResId( STR_UNDO_VECTORIZE ) ) );
                    pView->BegUndo( aStr );
                    pVectObj->SetGraphic( rMtf );
                    pView->ReplaceObject( pObj, *pPageView, pVectObj );
                    pView->EndUndo();
                }
            }
            delete pDlg;
        }
    }
}

} // end of namespace sd
<commit_msg>INTEGRATION: CWS aw035 (1.7.182); FILE MERGED 2006/07/13 16:05:15 aw 1.7.182.1: #126320# SdrMark::GetObj() -> SdrMark::GetMarkedSdrObj() for isolating selection handling<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fuvect.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2006-07-25 11:43:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "fuvect.hxx"

#ifndef _TL_POLY_HXX
#include <tools/poly.hxx>
#endif
#ifndef _SVDOPATH_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SVX_SVDOGRAF_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SVX_SVDEDTV_HXX //autogen
#include <svx/svdedtv.hxx>
#endif

#pragma hdrstop

#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#include "strings.hrc"
#include "sdresid.hxx"
//CHINA001 #include "vectdlg.hxx"
#include "sdabstdlg.hxx" //CHINA001
#include "vectdlg.hrc" //CHINA001
namespace sd {

TYPEINIT1( FuVectorize, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuVectorize::FuVectorize (
    ViewShell* pViewSh,
    ::sd::Window* pWin,
    ::sd::View* pView,
    SdDrawDocument* pDoc,
    SfxRequest& rReq)
    : FuPoor (pViewSh, pWin, pView, pDoc, rReq)
{
}

FunctionReference FuVectorize::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
{
    FunctionReference xFunc( new FuVectorize( pViewSh, pWin, pView, pDoc, rReq ) );
    xFunc->DoExecute(rReq);
    return xFunc;
}

void FuVectorize::DoExecute( SfxRequest& rReq )
{
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();

        if( pObj && pObj->ISA( SdrGrafObj ) )
        {
            SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
            AbstractSdVectorizeDlg* pDlg = pFact ? pFact->CreateSdVectorizeDlg(ResId( DLG_VECTORIZE ), pWindow, ( (SdrGrafObj*) pObj )->GetGraphic().GetBitmap(), pDocSh ) : 0;
            DBG_ASSERT(pDlg, "Dialogdiet fail!");
            if( pDlg && pDlg->Execute() == RET_OK )
            {
                const GDIMetaFile&  rMtf = pDlg->GetGDIMetaFile(); //CHINA001 const GDIMetaFile&    rMtf = aDlg.GetGDIMetaFile();
                SdrPageView*        pPageView = pView->GetPageViewPvNum( 0 );

                if( pPageView && rMtf.GetActionCount() )
                {
                    SdrGrafObj* pVectObj = (SdrGrafObj*) pObj->Clone();
                    String      aStr( pView->GetDescriptionOfMarkedObjects() );

                    aStr.Append( sal_Unicode(' ') );
                    aStr.Append( String( SdResId( STR_UNDO_VECTORIZE ) ) );
                    pView->BegUndo( aStr );
                    pVectObj->SetGraphic( rMtf );
                    pView->ReplaceObject( pObj, *pPageView, pVectObj );
                    pView->EndUndo();
                }
            }
            delete pDlg;
        }
    }
}

} // end of namespace sd
<|endoftext|>


<commit_before>#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <pthread.h>

#include "slre.h"

#include "../../utils/timer.h"
#include "../../utils/memoryman.h"

#define MAXCAPS 1000000
#define EXPRESSIONS 100
#define QUESTIONS 200

/* Data */
char *exps[256];
struct slre *slre[EXPRESSIONS];
char *bufs[MAXCAPS];
int temp[512], buf_len[512];
struct cap **caps;

int iterations;
int NTHREADS;
int numQs;
int numExps;
int s_max = 512;

void *slre_thread(void *tid) {
  int start, end, *mytid;
  mytid = (int *)tid;
  start = (*mytid * iterations);
  end = start + iterations;

  for (int i = start; i < end; ++i) {
    for (int j = 0; j < numQs; ++j) {
      slre_match(slre[i], bufs[j], buf_len[j], caps[i * numQs + j]);
    }
  }

  return NULL;
}

int fill(FILE *f, char **toFill, int *bufLen, int len) {
  int i = 0;

  while (i < len) {
    int ch = getc(f);
    if (ch == EOF) return i;
    bufLen[i] = 0;
    char *s = (char *)sirius_malloc(5000 + 1);
    while (1) {
      s[bufLen[i]] = ch;
      ++bufLen[i];
      ch = getc(f);
      if (ch == '\n') {
        s[bufLen[i]] = 0;
        toFill[i] = s;
        ++i;
        break;
      }
    }
  }
  return i;
}

int main(int argc, char *argv[]) {
  if (argc < 4) {
    fprintf(stderr, "[ERROR] Invalid arguments provided.\n\n");
    fprintf(stderr,
            "Usage: %s [NUMBER OF THREADS] [LIST FILE] [QUESTION FILE]\n\n",
            argv[0]);
    exit(0);
  }
  /* Timing */
  STATS_INIT("kernel", "regular_expression");
  PRINT_STAT_STRING("abrv", "pthread_regex");

  NTHREADS = atoi(argv[1]);
  PRINT_STAT_INT("threads", NTHREADS);

  FILE *f = fopen(argv[2], "r");
  if (f == 0) {
    fprintf(stderr, "File %s not found\n", argv[1]);
    exit(1);
  }
  numExps = fill(f, exps, temp, EXPRESSIONS);
  PRINT_STAT_INT("expressions", numExps);

  FILE *f1 = fopen(argv[3], "r");
  if (f1 == 0) {
    fprintf(stderr, "File %s not found\n", argv[2]);
    exit(1);
  }
  numQs = fill(f1, bufs, buf_len, QUESTIONS);
  PRINT_STAT_INT("questions", numQs);

  tic();
  for (int i = 0; i < numExps; ++i) {
    slre[i] = (struct slre *)sirius_malloc(sizeof(struct slre));
    if (!slre_compile(slre[i], exps[i])) {
      printf("error compiling: %s\n", exps[i]);
    }
  }
  PRINT_STAT_DOUBLE("regex_compile", toc());

  caps = (struct cap **)sirius_malloc(numExps * numQs * sizeof(struct cap));
  for (int i = 0; i < numExps * numQs; ++i) {
    char *s = (char *)sirius_malloc(s_max);
    struct cap *z = (struct cap *)sirius_malloc(sizeof(struct cap));
    z->ptr = s;
    caps[i] = z;
  }

  tic();

  int tids[NTHREADS];
  pthread_t threads[NTHREADS];
  pthread_attr_t attr;
  iterations = numExps / NTHREADS;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

  for (int i = 0; i < NTHREADS; i++) {
    tids[i] = i;
    pthread_create(&threads[i], &attr, slre_thread, (void *)&tids[i]);
  }

  for (int i = 0; i < NTHREADS; i++) pthread_join(threads[i], NULL);

  PRINT_STAT_DOUBLE("pthread_regex", toc());

#ifdef TESTING
  f = fopen("../input/regex_slre.pthread", "w");

  for (int i = 0; i < numExps * numQs; ++i) fprintf(f, "%s\n", caps[i]->ptr);

  fclose(f);
#endif

  sirius_free(caps);

  STATS_END();

  return 0;
}
<commit_msg>sirius-suite/regex/pthread/main.cpp: fix resource leak<commit_after>#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <pthread.h>

#include "slre.h"

#include "../../utils/timer.h"
#include "../../utils/memoryman.h"

#define MAXCAPS 1000000
#define EXPRESSIONS 100
#define QUESTIONS 200

/* Data */
char *exps[256];
struct slre *slre[EXPRESSIONS];
char *bufs[MAXCAPS];
int temp[512], buf_len[512];
struct cap **caps;

int iterations;
int NTHREADS;
int numQs;
int numExps;
int s_max = 512;

void *slre_thread(void *tid) {
  int start, end, *mytid;
  mytid = (int *)tid;
  start = (*mytid * iterations);
  end = start + iterations;

  for (int i = start; i < end; ++i) {
    for (int j = 0; j < numQs; ++j) {
      slre_match(slre[i], bufs[j], buf_len[j], caps[i * numQs + j]);
    }
  }

  return NULL;
}

int fill(FILE *f, char **toFill, int *bufLen, int len) {
  int i = 0;

  while (i < len) {
    int ch = getc(f);
    if (ch == EOF) return i;
    bufLen[i] = 0;
    char *s = (char *)sirius_malloc(5000 + 1);
    while (1) {
      s[bufLen[i]] = ch;
      ++bufLen[i];
      ch = getc(f);
      if (ch == '\n') {
        s[bufLen[i]] = 0;
        toFill[i] = s;
        ++i;
        break;
      }
    }
  }
  return i;
}

int main(int argc, char *argv[]) {
  if (argc < 4) {
    fprintf(stderr, "[ERROR] Invalid arguments provided.\n\n");
    fprintf(stderr,
            "Usage: %s [NUMBER OF THREADS] [LIST FILE] [QUESTION FILE]\n\n",
            argv[0]);
    exit(0);
  }
  /* Timing */
  STATS_INIT("kernel", "regular_expression");
  PRINT_STAT_STRING("abrv", "pthread_regex");

  NTHREADS = atoi(argv[1]);
  PRINT_STAT_INT("threads", NTHREADS);

  FILE *f = fopen(argv[2], "r");
  if (f == 0) {
    fprintf(stderr, "File %s not found\n", argv[1]);
    exit(1);
  }
  numExps = fill(f, exps, temp, EXPRESSIONS);
  PRINT_STAT_INT("expressions", numExps);

  FILE *f1 = fopen(argv[3], "r");
  if (f1 == 0) {
    fprintf(stderr, "File %s not found\n", argv[2]);
    exit(1);
  }
  numQs = fill(f1, bufs, buf_len, QUESTIONS);
  PRINT_STAT_INT("questions", numQs);

  tic();
  for (int i = 0; i < numExps; ++i) {
    slre[i] = (struct slre *)sirius_malloc(sizeof(struct slre));
    if (!slre_compile(slre[i], exps[i])) {
      printf("error compiling: %s\n", exps[i]);
    }
  }
  PRINT_STAT_DOUBLE("regex_compile", toc());

  caps = (struct cap **)sirius_malloc(numExps * numQs * sizeof(struct cap));
  for (int i = 0; i < numExps * numQs; ++i) {
    char *s = (char *)sirius_malloc(s_max);
    struct cap *z = (struct cap *)sirius_malloc(sizeof(struct cap));
    z->ptr = s;
    caps[i] = z;
  }

  tic();

  int tids[NTHREADS];
  pthread_t threads[NTHREADS];
  pthread_attr_t attr;
  iterations = numExps / NTHREADS;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

  for (int i = 0; i < NTHREADS; i++) {
    tids[i] = i;
    pthread_create(&threads[i], &attr, slre_thread, (void *)&tids[i]);
  }

  for (int i = 0; i < NTHREADS; i++) pthread_join(threads[i], NULL);

  PRINT_STAT_DOUBLE("pthread_regex", toc());

#ifdef TESTING
  fclose(f);
  f = fopen("../input/regex_slre.pthread", "w");

  for (int i = 0; i < numExps * numQs; ++i) fprintf(f, "%s\n", caps[i]->ptr);

#endif
  fclose(f);
  fclose(f1);

  sirius_free(caps);

  STATS_END();

  return 0;
}
<|endoftext|>


<commit_before>#include "cosine_tree.h"

// L2 norm of a specific column in a matrix
double columnNormL2(const Matrix& A, index_t i_col) {
  Vector col;
  A.MakeColumnVector(i_col, &col);
  return la::LengthEuclidean(col);
}

// Zero tolerance
#define eps (1e-16)
bool isZero(double d) {
  return (d<eps) && (d>-eps);
}

// Init a root cosine node from a matrix
CosineNode::CosineNode(const Matrix& A) {
  this->A_.Alias(A);
  origIndices_.reserve(A_.n_cols());
   norms_.reserve(A_.n_cols());

   int newval = A_.n_cols();

   for (index_t i_col = 0; i_col < A_.n_cols(); i_col++) {
        origIndices_.push_back(0);
        norms_.push_back(0);
    }

   for (index_t i_col = 0; i_col < A_.n_cols(); i_col++) {
        origIndices_[i_col] = i_col;
        norms_[i_col] = columnNormL2(A_, i_col);
  }

  parent_ = NULL;
  left_ = NULL;
  right_ = NULL;
  isLeft_ = false;

  CalStats();
}

// Init a child cosine node from its parent and a set of the parent's columns
CosineNode::CosineNode(CosineNode& parent,
		       const std::vector<int>& indices, bool isLeft) {
  A_.Alias(parent.A_);
  origIndices_.reserve(indices.size());
  norms_.reserve(n_cols());

for(index_t i_col = 0; i_col < indices.size(); i_col++) {
      norms_.push_back(0);
      origIndices_.push_back(0);
   }

  for (index_t i_col = 0; i_col < origIndices_.size(); i_col++) {
    origIndices_[i_col] = parent.origIndices_[indices[i_col]];
    norms_[i_col] = parent.norms_[indices[i_col]];
  }
  parent_ = &parent;
  left_ = NULL;
  right_ = NULL;
  isLeft_ = isLeft;

  if (isLeft) parent.left_ = this;
  else parent.right_ = this;
  CalStats();
}

void CosineNode::CalStats() {
  // Calculate cummlulative sum square of L2 norms

 cum_norms_.reserve(A_.n_cols());

  for (index_t i_col = 0; i_col < A_.n_cols(); i_col++) {
     cum_norms_.push_back(0);
  }

  for (index_t i_col = 0; i_col < A_.n_cols(); i_col++) {
  cum_norms_[i_col] = ((i_col > 0) ? cum_norms_[i_col-1]:0)
      + math::Sqr(norms_[i_col]);
  }
  // Calculate mean vector
  mean_.Init(A_.n_rows()); mean_.SetZero();
  for (index_t i_col = 0; i_col < n_cols(); i_col++) {
    Vector col;
    GetColumn(i_col, &col);
    la::AddTo(col, &mean_);
  }
  la::Scale(1.0/(double)origIndices_.size(), &mean_);
}

void CosineNode::ChooseCenter(Vector* center) {

  double r = (double)rand()/RAND_MAX * cum_norms_[n_cols()-1];
  index_t i_col;
  for (i_col = 0; i_col < n_cols(); i_col++)
    if (cum_norms_[i_col] >= r) break;
  GetColumn(i_col, center);
}

void CosineNode::CalCosines(const Vector& center,
			    std::vector<double>* cosines) {

  for(index_t i_col=0; i_col < n_cols(); i_col++) {
    (*cosines).push_back(0);
  }

  double centerL2 = la::LengthEuclidean(center);

 for (index_t i_col = 0; i_col < n_cols(); i_col++)
  {
    // if col is a zero vector then push it to the left node
    if (isZero(norms_[i_col]))
      (*cosines)[i_col] = 2;
    else {
      Vector col;
      GetColumn(i_col, &col);
      double numerator = la::Dot(center, col);
      double denominator = centerL2 * norms_[i_col];
      (*cosines)[i_col] = numerator/denominator;
    }
  }
}

void CosineNode::CreateIndices(std::vector<int>* indices) {
  indices->reserve(n_cols());

   for (index_t i_col = 0; i_col < n_cols(); i_col++)
   {
      (*indices).push_back(0);
   }

   for (index_t i_col = 0; i_col < n_cols(); i_col++)
    (*indices)[i_col] = i_col;
}

// Quicksort partitioning procedure
index_t qpartition(std::vector<double>& key, std::vector<int>& data,
		index_t left, index_t right) {
  index_t j = left;
  double x = key[left];

 for (index_t i = left+1; i <= right; i++)
  {

   if (key[i] >= x) {
      j++;
      double tmp_d = key[i]; key[i] = key[j]; key[j] = tmp_d;
      index_t tmp_i = data[i]; data[i] = data[j]; data[j] = tmp_i;
    }
   }

  double tmp_d = key[left]; key[left] = key[j]; key[j] = tmp_d;
  index_t tmp_i = data[left]; data[left] = data[j]; data[j] = tmp_i;
  return j;
}

// Quicksort on the cosine values
void qsort(std::vector<double>& key, std::vector<int>& data,
	   index_t left, index_t right) {

 if (left >= right) return;
  index_t middle = qpartition(key, data, left, right);
  qsort(key, data, left, middle-1);
  qsort(key, data, middle+1, right);
}

void Sort(std::vector<double>& key, std::vector<int>& data) {
  qsort(key, data, 0, key.size()-1);
}

// Calculate the split point where the cosines values are closer
// to the minimum cosine value than the maximum cosine value
index_t calSplitPoint(const std::vector<double>& key) {
  double leftKey = key[0];
  double rightKey = key[key.size()-1];
  index_t i = 0;
  while (leftKey - key[i] <= key[i] - rightKey && i < key.size()) i++;
  //printf("i = %d\n", i);
  return i;
}

// Init a subcopy of an array list
void InitSubCopy(const std::vector<int>& src, index_t pos, index_t size,
		 std::vector<int>* dst) {

   dst->reserve(size);
   for (index_t i = 0; i < size; i++)
    (*dst).push_back(0);

   for (index_t i = 0; i < size; i++)
    (*dst)[i] = src[pos+i];
}

// Split the indices at the split point
void splitIndices(std::vector<int>& indices, int leftSize,
		  std::vector<int>* leftIdx, std::vector<int>* rightIdx) {
  InitSubCopy(indices, 0, leftSize, leftIdx);
  InitSubCopy(indices, leftSize, indices.size()-leftSize, rightIdx);
}

// Split a cosine tree node by choose a random center, and sort
// the cosine values decreasingly, then choose a split point
// by calling calSplitPoint()
// This procedure won't split a node if either child has the same
// set of columns as the parent
void CosineNode::Split() {

  if (n_cols() < 2) return;
  Vector center;
  std::vector<double> cosines;
  std::vector<int> indices, leftIdx, rightIdx;

  ChooseCenter(&center);

  CalCosines(center, &cosines);

  CreateIndices(&indices);

  Sort(cosines, indices);

  index_t leftSize = calSplitPoint(cosines);

  if (leftSize == n_cols() || leftSize == 0) return;

  splitIndices(indices, leftSize, &leftIdx, &rightIdx);

  left_ = new CosineNode(*this, leftIdx, true);
  right_ = new CosineNode(*this, rightIdx, false);
}

<commit_msg>--Convert to boost unit test framework, ticket 85; replace reserve with resize()<commit_after>#include "cosine_tree.h"

// L2 norm of a specific column in a matrix
double columnNormL2(const Matrix& A, index_t i_col) {
  Vector col;
  A.MakeColumnVector(i_col, &col);
  return la::LengthEuclidean(col);
}

// Zero tolerance
#define eps (1e-16)
bool isZero(double d) {
  return (d<eps) && (d>-eps);
}

// Init a root cosine node from a matrix
CosineNode::CosineNode(const Matrix& A) {
  this->A_.Alias(A);
  origIndices_.resize(A_.n_cols());
   norms_.resize(A_.n_cols());

   int newval = A_.n_cols();

   for (index_t i_col = 0; i_col < A_.n_cols(); i_col++) {
        origIndices_[i_col] = i_col;
        norms_[i_col] = columnNormL2(A_, i_col);
  }

  parent_ = NULL;
  left_ = NULL;
  right_ = NULL;
  isLeft_ = false;

  CalStats();
}

// Init a child cosine node from its parent and a set of the parent's columns
CosineNode::CosineNode(CosineNode& parent,
		       const std::vector<int>& indices, bool isLeft) {
  A_.Alias(parent.A_);
  origIndices_.resize(indices.size());
  norms_.resize(n_cols());

  for (index_t i_col = 0; i_col < origIndices_.size(); i_col++) {
    origIndices_[i_col] = parent.origIndices_[indices[i_col]];
    norms_[i_col] = parent.norms_[indices[i_col]];
  }
  parent_ = &parent;
  left_ = NULL;
  right_ = NULL;
  isLeft_ = isLeft;

  if (isLeft) parent.left_ = this;
  else parent.right_ = this;
  CalStats();
}

void CosineNode::CalStats() {
  // Calculate cummlulative sum square of L2 norms

  cum_norms_.resize(A_.n_cols());

  for (index_t i_col = 0; i_col < A_.n_cols(); i_col++) {
  cum_norms_[i_col] = ((i_col > 0) ? cum_norms_[i_col-1]:0)
      + math::Sqr(norms_[i_col]);
  }
  // Calculate mean vector
  mean_.Init(A_.n_rows()); mean_.SetZero();
  for (index_t i_col = 0; i_col < n_cols(); i_col++) {
    Vector col;
    GetColumn(i_col, &col);
    la::AddTo(col, &mean_);
  }
  la::Scale(1.0/(double)origIndices_.size(), &mean_);
}

void CosineNode::ChooseCenter(Vector* center) {

  double r = (double)rand()/RAND_MAX * cum_norms_[n_cols()-1];
  index_t i_col;
  for (i_col = 0; i_col < n_cols(); i_col++)
    if (cum_norms_[i_col] >= r) break;
  GetColumn(i_col, center);
}

void CosineNode::CalCosines(const Vector& center,
			    std::vector<double>* cosines) {

  double centerL2 = la::LengthEuclidean(center);

 for (index_t i_col = 0; i_col < n_cols(); i_col++)
  {
    // if col is a zero vector then push it to the left node
    if (isZero(norms_[i_col]))
      (*cosines)[i_col] = 2;
    else {
      Vector col;
      GetColumn(i_col, &col);
      double numerator = la::Dot(center, col);
      double denominator = centerL2 * norms_[i_col];
      (*cosines)[i_col] = numerator/denominator;
    }
  }
}

void CosineNode::CreateIndices(std::vector<int>* indices) {

   indices->resize(n_cols());

   for (index_t i_col = 0; i_col < n_cols(); i_col++)
    (*indices)[i_col] = i_col;
}

// Quicksort partitioning procedure
index_t qpartition(std::vector<double>& key, std::vector<int>& data,
		index_t left, index_t right) {
  index_t j = left;
  double x = key[left];

 for (index_t i = left+1; i <= right; i++)
  {

   if (key[i] >= x) {
      j++;
      double tmp_d = key[i]; key[i] = key[j]; key[j] = tmp_d;
      index_t tmp_i = data[i]; data[i] = data[j]; data[j] = tmp_i;
    }
   }

  double tmp_d = key[left]; key[left] = key[j]; key[j] = tmp_d;
  index_t tmp_i = data[left]; data[left] = data[j]; data[j] = tmp_i;
  return j;
}

// Quicksort on the cosine values
void qsort(std::vector<double>& key, std::vector<int>& data,
	   index_t left, index_t right) {

 if (left >= right) return;
  index_t middle = qpartition(key, data, left, right);
  qsort(key, data, left, middle-1);
  qsort(key, data, middle+1, right);
}

void Sort(std::vector<double>& key, std::vector<int>& data) {
  qsort(key, data, 0, key.size()-1);
}

// Calculate the split point where the cosines values are closer
// to the minimum cosine value than the maximum cosine value
index_t calSplitPoint(const std::vector<double>& key) {
  double leftKey = key[0];
  double rightKey = key[key.size()-1];
  index_t i = 0;
  while (leftKey - key[i] <= key[i] - rightKey && i < key.size()) i++;
  //printf("i = %d\n", i);
  return i;
}

// Init a subcopy of an array list
void InitSubCopy(const std::vector<int>& src, index_t pos, index_t size,
		 std::vector<int>* dst) {

   dst->resize(size);

   for (index_t i = 0; i < size; i++)
    (*dst)[i] = src[pos+i];
}

// Split the indices at the split point
void splitIndices(std::vector<int>& indices, int leftSize,
		  std::vector<int>* leftIdx, std::vector<int>* rightIdx) {
  InitSubCopy(indices, 0, leftSize, leftIdx);
  InitSubCopy(indices, leftSize, indices.size()-leftSize, rightIdx);
}

// Split a cosine tree node by choose a random center, and sort
// the cosine values decreasingly, then choose a split point
// by calling calSplitPoint()
// This procedure won't split a node if either child has the same
// set of columns as the parent
void CosineNode::Split() {

  if (n_cols() < 2) return;
  Vector center;
  std::vector<double> cosines;
  std::vector<int> indices, leftIdx, rightIdx;

  ChooseCenter(&center);

  CalCosines(center, &cosines);

  CreateIndices(&indices);

  Sort(cosines, indices);

  index_t leftSize = calSplitPoint(cosines);

  if (leftSize == n_cols() || leftSize == 0) return;

  splitIndices(indices, leftSize, &leftIdx, &rightIdx);

  left_ = new CosineNode(*this, leftIdx, true);
  right_ = new CosineNode(*this, rightIdx, false);
}

<|endoftext|>