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

// Renderer that is using 2D Library Cairo.

#include "core/cross/cairo/renderer_cairo.h"
#include <cairo-xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "core/cross/cairo/layer.h"
#include "core/cross/cairo/texture_cairo.h"

namespace o3d {

Renderer* Renderer::CreateDefaultRenderer(ServiceLocator* service_locator) {
  return o2d::RendererCairo::CreateDefault(service_locator);
}

namespace o2d {

RendererCairo::RendererCairo(ServiceLocator* service_locator)
    : Renderer(service_locator), display_(NULL), main_surface_(NULL) {
  // Don't need to do anything.
}

RendererCairo::~RendererCairo() {
  Destroy();
}

RendererCairo* RendererCairo::CreateDefault(ServiceLocator* service_locator) {
  return new RendererCairo(service_locator);
}

// Released all hardware resources.
void RendererCairo::Destroy() {
  DLOG(INFO) << "To Destroy";

  if (main_surface_ != NULL) {
    cairo_surface_destroy(main_surface_);
    main_surface_= NULL;
  }

  display_ = NULL;
}

// Comparison predicate for STL sort.
bool LayerZValueLessThan(const Layer* first, const Layer* second) {
  return first->z() < second->z();
}

void RendererCairo::Paint() {
  // TODO(tschmelcher): Don't keep creating and destroying the drawing context.
  cairo_t* current_drawing = cairo_create(main_surface_);

  // Redirect drawing to an off-screen surface (holding only colour information,
  // without an alpha channel).
  cairo_push_group_with_content(current_drawing, CAIRO_CONTENT_COLOR);

  // Sort layers by z value.
  // TODO(tschmelcher): Only sort when changes are made.
  layer_list_.sort(LayerZValueLessThan);

  // Paint the background.
  PaintBackground(current_drawing);

  // Core process of painting.
  for (LayerList::iterator i = layer_list_.begin();
       i != layer_list_.end(); i++) {
    Layer* cur = *i;
    if (!cur->ShouldPaint()) continue;

    Pattern* pattern = cur->pattern();

    // Save the current drawing state.
    cairo_save(current_drawing);

    // Clip areas that will be obscured anyway.
    LayerList::iterator start_mask_it = i;
    start_mask_it++;
    ClipArea(current_drawing, start_mask_it);

    // Define the region to fill.
    cairo_rectangle(current_drawing,
                    cur->x(),
                    cur->y(),
                    cur->width(),
                    cur->height());

    // Transform the pattern to fit into the fill region.
    cairo_translate(current_drawing, cur->x(), cur->y());
    cairo_scale(current_drawing, cur->scale_x(), cur->scale_y());

    // Set source pattern.
    cairo_set_source(current_drawing, pattern->pattern());

    // Paint the pattern to the off-screen surface.
    switch (cur->paint_operator()) {
      case Layer::BLEND:
        cairo_fill(current_drawing);
        break;

      case Layer::BLEND_WITH_TRANSPARENCY:
        {
          cairo_pattern_t* mask = cairo_pattern_create_rgba(0.0,
                                                            0.0,
                                                            0.0,
                                                            cur->alpha());
          cairo_mask(current_drawing, mask);
          cairo_pattern_destroy(mask);
        }
        break;

        // TODO(tschmelcher): COPY_WITH_FADING is not implemented yet. For now
        // we treat it the same as COPY.
      case Layer::COPY_WITH_FADING:
      case Layer::COPY:
        // Set Cairo to copy the pattern's alpha content instead of blending.
        cairo_set_operator(current_drawing, CAIRO_OPERATOR_SOURCE);
        cairo_fill(current_drawing);
        break;

      default:
        DCHECK(false);
    }

    // Restore to a clean state.
    cairo_restore(current_drawing);
  }

  // Finish off-screen drawing and make the off-screen surface the source for
  // paints to the screen.
  cairo_pop_group_to_source(current_drawing);

  // Paint the off-screen surface to the screen.
  cairo_paint(current_drawing);

  cairo_destroy(current_drawing);
}

void RendererCairo::PaintBackground(cairo_t* cr) {
  cairo_save(cr);
  ClipArea(cr, layer_list_.begin());

  cairo_rectangle(cr, 0, 0, display_width(), display_height());
  cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  cairo_fill(cr);
  cairo_restore(cr);
}

void RendererCairo::ClipArea(cairo_t* cr,  LayerList::iterator it) {
  cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);

  for (LayerList::iterator i = it; i != layer_list_.end(); i++) {
    // Preparing and updating the Layer.
    Layer* cur = *i;
    if (!cur->ShouldClip()) continue;

    cairo_rectangle(cr, 0, 0, display_width(), display_height());
    cairo_rectangle(cr,
                    cur->x(),
                    cur->y(),
                    cur->width(),
                    cur->height());
    cairo_clip(cr);
  }
}

void RendererCairo::AddLayer(Layer* image) {
  layer_list_.push_front(image);
}

void RendererCairo::RemoveLayer(Layer* image) {
  layer_list_.remove(image);
}

void RendererCairo::InitCommon() {
  main_surface_ = cairo_xlib_surface_create(display_, window_,
                                            XDefaultVisual(display_, 0),
                                            display_width(), display_height());
}

void RendererCairo::UninitCommon() {
  // Don't need to do anything.
}

Renderer::InitStatus RendererCairo::InitPlatformSpecific(
    const DisplayWindow& display_window,
    bool off_screen) {
  const DisplayWindowLinux &display_platform =
      static_cast<const DisplayWindowLinux&>(display_window);
  display_ = display_platform.display();
  window_ = display_platform.window();

  return SUCCESS;
}

// Handles the plugin resize event.
void RendererCairo::Resize(int width, int height) {
  DLOG(INFO) << "To Resize " << width << " x " << height;
  SetClientSize(width, height);

  // Resize the mainSurface and buffer
  cairo_xlib_surface_set_size(main_surface_, width, height);
}

// The platform specific part of BeginDraw.
bool RendererCairo::PlatformSpecificBeginDraw() {
  return true;
}

// Platform specific version of CreateTexture2D
Texture2D::Ref RendererCairo::CreatePlatformSpecificTexture2D(
    int width,
    int height,
    Texture::Format format,
    int levels,
    bool enable_render_surfaces) {
  return Texture2D::Ref(TextureCairo::Create(service_locator(),
                                             format,
                                             levels,
                                             width,
                                             height,
                                             enable_render_surfaces));
}

// The platform specific part of EndDraw.
void RendererCairo::PlatformSpecificEndDraw() {
  // Don't need to do anything.
}

// The platform specific part of StartRendering.
bool RendererCairo::PlatformSpecificStartRendering() {
  return true;
}

// The platform specific part of EndRendering.
void RendererCairo::PlatformSpecificFinishRendering() {
  Paint();
}

// The platform specific part of Present.
void RendererCairo::PlatformSpecificPresent() {
  // Don't need to do anything.
}

// TODO(fransiskusx): DO need to implement before shipped.
// Get a single fullscreen display mode by id.
// Returns true on success, false on error.
bool RendererCairo::GetDisplayMode(int id, DisplayMode* mode) {
  NOTIMPLEMENTED();
  return true;
}

// TODO(fransiskusx):  DO need to implement before shipped.
// Get a vector of the available fullscreen display modes.
// Clears *modes on error.
void RendererCairo::GetDisplayModes(std::vector<DisplayMode>* modes) {
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): DO need to implement before shipped.
// The platform specific part of Clear.
void RendererCairo::PlatformSpecificClear(const Float4 &color,
                                          bool color_flag,
                                          float depth,
                                          bool depth_flag,
                                          int stencil,
                                          bool stencil_flag) {
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): DO need to implement before shipped.
// Sets the viewport. This is the platform specific version.
void RendererCairo::SetViewportInPixels(int left,
                                        int top,
                                        int width,
                                        int height,
                                        float min_z,
                                        float max_z) {
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): Need to implement it later.
// Turns fullscreen display on.
// Parameters:
//  display: a platform-specific display identifier
//  mode_id: a mode returned by GetDisplayModes
// Returns true on success, false on failure.
bool RendererCairo::GoFullscreen(const DisplayWindow& display,
                                 int mode_id) {
  NOTIMPLEMENTED();
  return false;
}

// TODO(fransiskusx): Need to implement it later.
// Cancels fullscreen display. Restores rendering to windowed mode
// with the given width and height.
// Parameters:
//  display: a platform-specific display identifier
//  width: the width to which to restore windowed rendering
//  height: the height to which to restore windowed rendering
// Returns true on success, false on failure.
bool RendererCairo::CancelFullscreen(const DisplayWindow& display,
                                     int width, int height) {
  NOTIMPLEMENTED();
  return false;
}

// TODO(fransiskusx): Need to implement it later.
// Tells whether we're currently displayed fullscreen or not.
bool RendererCairo::fullscreen() const {
  NOTIMPLEMENTED();
  return false;
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Sets rendering to the back buffer.
void RendererCairo::SetBackBufferPlatformSpecific() {
  // Don't need to do anything.
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Applies states that have been modified (marked dirty).
void RendererCairo::ApplyDirtyStates() {
  // Don't need to do anything.
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates a platform specific ParamCache.
ParamCache* RendererCairo::CreatePlatformSpecificParamCache() {
  NOTIMPLEMENTED();
  return NULL;
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Platform specific version of CreateTextureCUBE.
TextureCUBE::Ref RendererCairo::CreatePlatformSpecificTextureCUBE(
    int edge_length,
    Texture::Format format,
    int levels,
    bool enable_render_surfaces) {
  NOTIMPLEMENTED();
  return TextureCUBE::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
void RendererCairo::PushRenderStates(State* state) {
  // Don't need to do anything.;
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Sets the render surfaces on a specific platform.
void RendererCairo::SetRenderSurfacesPlatformSpecific(
    const RenderSurface* surface,
    const RenderDepthStencilSurface* depth_surface) {
  // Don't need to do anything.
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates a StreamBank, returning a platform specific implementation class.
StreamBank::Ref RendererCairo::CreateStreamBank() {
  NOTIMPLEMENTED();
  return StreamBank::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates a Primitive, returning a platform specific implementation class.
Primitive::Ref RendererCairo::CreatePrimitive() {
  NOTIMPLEMENTED();
  return Primitive::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates a DrawElement, returning a platform specific implementation
// class.
DrawElement::Ref RendererCairo::CreateDrawElement() {
  NOTIMPLEMENTED();
  return DrawElement::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform specific float buffer
VertexBuffer::Ref RendererCairo::CreateVertexBuffer() {
  NOTIMPLEMENTED();
  return VertexBuffer::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform specific integer buffer
IndexBuffer::Ref RendererCairo::CreateIndexBuffer() {
  NOTIMPLEMENTED();
  return IndexBuffer::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform specific effect object
Effect::Ref RendererCairo::CreateEffect() {
  NOTIMPLEMENTED();
  return Effect::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform specific Sampler object.
Sampler::Ref RendererCairo::CreateSampler() {
  NOTIMPLEMENTED();
  return Sampler::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Returns a platform specific 4 element swizzle table for RGBA UByteN fields.
// The should contain the index of R, G, B, and A in that order for the
// current platform.
const int* RendererCairo::GetRGBAUByteNSwizzleTable() {
  static int swizzle_table[] = { 0, 1, 2, 3, };
  NOTIMPLEMENTED();
  return swizzle_table;
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform-specific RenderDepthStencilSurface object
// for use as a depth-stencil render target.
RenderDepthStencilSurface::Ref RendererCairo::CreateDepthStencilSurface(
    int width,
    int height) {
  NOTIMPLEMENTED();
  return RenderDepthStencilSurface::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
void RendererCairo::SetState(Renderer* renderer, Param* param) {
  // Don't need to do anything.
  NOTIMPLEMENTED();
}

void RendererCairo::PopRenderStates() {
  NOTIMPLEMENTED();
}

}  // namespace o2d

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

// Renderer that is using 2D Library Cairo.

#include "core/cross/cairo/renderer_cairo.h"
#include <cairo-xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "core/cross/cairo/layer.h"
#include "core/cross/cairo/texture_cairo.h"

namespace o3d {

Renderer* Renderer::CreateDefaultRenderer(ServiceLocator* service_locator) {
  return o2d::RendererCairo::CreateDefault(service_locator);
}

namespace o2d {

RendererCairo::RendererCairo(ServiceLocator* service_locator)
    : Renderer(service_locator), display_(NULL), main_surface_(NULL) {
  // Don't need to do anything.
}

RendererCairo::~RendererCairo() {
  Destroy();
}

RendererCairo* RendererCairo::CreateDefault(ServiceLocator* service_locator) {
  return new RendererCairo(service_locator);
}

// Released all hardware resources.
void RendererCairo::Destroy() {
  DLOG(INFO) << "To Destroy";

  if (main_surface_ != NULL) {
    cairo_surface_destroy(main_surface_);
    main_surface_= NULL;
  }

  display_ = NULL;
}

// Comparison predicate for STL sort.
bool LayerZValueLessThan(const Layer* first, const Layer* second) {
  return first->z() < second->z();
}

void RendererCairo::Paint() {
  // TODO(tschmelcher): Don't keep creating and destroying the drawing context.
  cairo_t* current_drawing = cairo_create(main_surface_);

  // Redirect drawing to an off-screen surface (holding only colour information,
  // without an alpha channel).
  cairo_push_group_with_content(current_drawing, CAIRO_CONTENT_COLOR);

  // Set fill (and clip) rule.
  cairo_set_fill_rule(current_drawing, CAIRO_FILL_RULE_EVEN_ODD);

  // Sort layers by z value.
  // TODO(tschmelcher): Only sort when changes are made.
  layer_list_.sort(LayerZValueLessThan);

  // Paint the background.
  PaintBackground(current_drawing);

  // Core process of painting.
  for (LayerList::iterator i = layer_list_.begin();
       i != layer_list_.end(); i++) {
    Layer* cur = *i;
    if (!cur->ShouldPaint()) continue;

    Pattern* pattern = cur->pattern();

    // Save the current drawing state.
    cairo_save(current_drawing);

    // Clip the region outside the current Layer.
    cairo_rectangle(current_drawing,
                    cur->x(),
                    cur->y(),
                    cur->width(),
                    cur->height());
    cairo_clip(current_drawing);

    // Clip the regions within other Layers that will obscure this one.
    LayerList::iterator start_mask_it = i;
    start_mask_it++;
    ClipArea(current_drawing, start_mask_it);

    // Transform the pattern to fit into the Layer's region.
    cairo_translate(current_drawing, cur->x(), cur->y());
    cairo_scale(current_drawing, cur->scale_x(), cur->scale_y());

    // Set source pattern.
    cairo_set_source(current_drawing, pattern->pattern());

    // Paint the pattern to the off-screen surface.
    switch (cur->paint_operator()) {
      case Layer::BLEND:
        cairo_paint(current_drawing);
        break;

      case Layer::BLEND_WITH_TRANSPARENCY:
        cairo_paint_with_alpha(current_drawing, cur->alpha());
        break;

      case Layer::COPY:
        // Set Cairo to copy the pattern's alpha content instead of blending.
        cairo_set_operator(current_drawing, CAIRO_OPERATOR_SOURCE);
        cairo_paint(current_drawing);
        break;

      case Layer::COPY_WITH_FADING:
        // TODO(tschmelcher): This can also be done in a single operation with:
        //
        //   cairo_set_operator(current_drawing, CAIRO_OPERATOR_IN);
        //   cairo_paint_with_alpha(current_drawing, cur->alpha());
        //
        // but surprisingly that is slightly slower for me. We should figure out
        // why.
        cairo_set_operator(current_drawing, CAIRO_OPERATOR_CLEAR);
        cairo_paint(current_drawing);
        cairo_set_operator(current_drawing, CAIRO_OPERATOR_OVER);
        cairo_paint_with_alpha(current_drawing, cur->alpha());
        break;

      default:
        DCHECK(false);
    }

    // Restore to a clean state.
    cairo_restore(current_drawing);
  }

  // Finish off-screen drawing and make the off-screen surface the source for
  // paints to the screen.
  cairo_pop_group_to_source(current_drawing);

  // Paint the off-screen surface to the screen.
  cairo_paint(current_drawing);

  cairo_destroy(current_drawing);
}

void RendererCairo::PaintBackground(cairo_t* cr) {
  cairo_save(cr);
  ClipArea(cr, layer_list_.begin());

  cairo_rectangle(cr, 0, 0, display_width(), display_height());
  cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  cairo_fill(cr);
  cairo_restore(cr);
}

void RendererCairo::ClipArea(cairo_t* cr,  LayerList::iterator it) {
  for (LayerList::iterator i = it; i != layer_list_.end(); i++) {
    // Preparing and updating the Layer.
    Layer* cur = *i;
    if (!cur->ShouldClip()) continue;

    cairo_rectangle(cr, 0, 0, display_width(), display_height());
    cairo_rectangle(cr,
                    cur->x(),
                    cur->y(),
                    cur->width(),
                    cur->height());
    cairo_clip(cr);
  }
}

void RendererCairo::AddLayer(Layer* image) {
  layer_list_.push_front(image);
}

void RendererCairo::RemoveLayer(Layer* image) {
  layer_list_.remove(image);
}

void RendererCairo::InitCommon() {
  main_surface_ = cairo_xlib_surface_create(display_, window_,
                                            XDefaultVisual(display_, 0),
                                            display_width(), display_height());
}

void RendererCairo::UninitCommon() {
  // Don't need to do anything.
}

Renderer::InitStatus RendererCairo::InitPlatformSpecific(
    const DisplayWindow& display_window,
    bool off_screen) {
  const DisplayWindowLinux &display_platform =
      static_cast<const DisplayWindowLinux&>(display_window);
  display_ = display_platform.display();
  window_ = display_platform.window();

  return SUCCESS;
}

// Handles the plugin resize event.
void RendererCairo::Resize(int width, int height) {
  DLOG(INFO) << "To Resize " << width << " x " << height;
  SetClientSize(width, height);

  // Resize the mainSurface and buffer
  cairo_xlib_surface_set_size(main_surface_, width, height);
}

// The platform specific part of BeginDraw.
bool RendererCairo::PlatformSpecificBeginDraw() {
  return true;
}

// Platform specific version of CreateTexture2D
Texture2D::Ref RendererCairo::CreatePlatformSpecificTexture2D(
    int width,
    int height,
    Texture::Format format,
    int levels,
    bool enable_render_surfaces) {
  return Texture2D::Ref(TextureCairo::Create(service_locator(),
                                             format,
                                             levels,
                                             width,
                                             height,
                                             enable_render_surfaces));
}

// The platform specific part of EndDraw.
void RendererCairo::PlatformSpecificEndDraw() {
  // Don't need to do anything.
}

// The platform specific part of StartRendering.
bool RendererCairo::PlatformSpecificStartRendering() {
  return true;
}

// The platform specific part of EndRendering.
void RendererCairo::PlatformSpecificFinishRendering() {
  Paint();
}

// The platform specific part of Present.
void RendererCairo::PlatformSpecificPresent() {
  // Don't need to do anything.
}

// TODO(fransiskusx): DO need to implement before shipped.
// Get a single fullscreen display mode by id.
// Returns true on success, false on error.
bool RendererCairo::GetDisplayMode(int id, DisplayMode* mode) {
  NOTIMPLEMENTED();
  return true;
}

// TODO(fransiskusx):  DO need to implement before shipped.
// Get a vector of the available fullscreen display modes.
// Clears *modes on error.
void RendererCairo::GetDisplayModes(std::vector<DisplayMode>* modes) {
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): DO need to implement before shipped.
// The platform specific part of Clear.
void RendererCairo::PlatformSpecificClear(const Float4 &color,
                                          bool color_flag,
                                          float depth,
                                          bool depth_flag,
                                          int stencil,
                                          bool stencil_flag) {
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): DO need to implement before shipped.
// Sets the viewport. This is the platform specific version.
void RendererCairo::SetViewportInPixels(int left,
                                        int top,
                                        int width,
                                        int height,
                                        float min_z,
                                        float max_z) {
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): Need to implement it later.
// Turns fullscreen display on.
// Parameters:
//  display: a platform-specific display identifier
//  mode_id: a mode returned by GetDisplayModes
// Returns true on success, false on failure.
bool RendererCairo::GoFullscreen(const DisplayWindow& display,
                                 int mode_id) {
  NOTIMPLEMENTED();
  return false;
}

// TODO(fransiskusx): Need to implement it later.
// Cancels fullscreen display. Restores rendering to windowed mode
// with the given width and height.
// Parameters:
//  display: a platform-specific display identifier
//  width: the width to which to restore windowed rendering
//  height: the height to which to restore windowed rendering
// Returns true on success, false on failure.
bool RendererCairo::CancelFullscreen(const DisplayWindow& display,
                                     int width, int height) {
  NOTIMPLEMENTED();
  return false;
}

// TODO(fransiskusx): Need to implement it later.
// Tells whether we're currently displayed fullscreen or not.
bool RendererCairo::fullscreen() const {
  NOTIMPLEMENTED();
  return false;
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Sets rendering to the back buffer.
void RendererCairo::SetBackBufferPlatformSpecific() {
  // Don't need to do anything.
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Applies states that have been modified (marked dirty).
void RendererCairo::ApplyDirtyStates() {
  // Don't need to do anything.
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates a platform specific ParamCache.
ParamCache* RendererCairo::CreatePlatformSpecificParamCache() {
  NOTIMPLEMENTED();
  return NULL;
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Platform specific version of CreateTextureCUBE.
TextureCUBE::Ref RendererCairo::CreatePlatformSpecificTextureCUBE(
    int edge_length,
    Texture::Format format,
    int levels,
    bool enable_render_surfaces) {
  NOTIMPLEMENTED();
  return TextureCUBE::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
void RendererCairo::PushRenderStates(State* state) {
  // Don't need to do anything.;
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Sets the render surfaces on a specific platform.
void RendererCairo::SetRenderSurfacesPlatformSpecific(
    const RenderSurface* surface,
    const RenderDepthStencilSurface* depth_surface) {
  // Don't need to do anything.
  NOTIMPLEMENTED();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates a StreamBank, returning a platform specific implementation class.
StreamBank::Ref RendererCairo::CreateStreamBank() {
  NOTIMPLEMENTED();
  return StreamBank::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates a Primitive, returning a platform specific implementation class.
Primitive::Ref RendererCairo::CreatePrimitive() {
  NOTIMPLEMENTED();
  return Primitive::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates a DrawElement, returning a platform specific implementation
// class.
DrawElement::Ref RendererCairo::CreateDrawElement() {
  NOTIMPLEMENTED();
  return DrawElement::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform specific float buffer
VertexBuffer::Ref RendererCairo::CreateVertexBuffer() {
  NOTIMPLEMENTED();
  return VertexBuffer::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform specific integer buffer
IndexBuffer::Ref RendererCairo::CreateIndexBuffer() {
  NOTIMPLEMENTED();
  return IndexBuffer::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform specific effect object
Effect::Ref RendererCairo::CreateEffect() {
  NOTIMPLEMENTED();
  return Effect::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform specific Sampler object.
Sampler::Ref RendererCairo::CreateSampler() {
  NOTIMPLEMENTED();
  return Sampler::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Returns a platform specific 4 element swizzle table for RGBA UByteN fields.
// The should contain the index of R, G, B, and A in that order for the
// current platform.
const int* RendererCairo::GetRGBAUByteNSwizzleTable() {
  static int swizzle_table[] = { 0, 1, 2, 3, };
  NOTIMPLEMENTED();
  return swizzle_table;
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
// Creates and returns a platform-specific RenderDepthStencilSurface object
// for use as a depth-stencil render target.
RenderDepthStencilSurface::Ref RendererCairo::CreateDepthStencilSurface(
    int width,
    int height) {
  NOTIMPLEMENTED();
  return RenderDepthStencilSurface::Ref();
}

// TODO(fransiskusx): This function is not applicable to 2D rendering.
void RendererCairo::SetState(Renderer* renderer, Param* param) {
  // Don't need to do anything.
  NOTIMPLEMENTED();
}

void RendererCairo::PopRenderStates() {
  NOTIMPLEMENTED();
}

}  // namespace o2d

}  // namespace o3d
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 New Designs Unlimited, LLC
 * Opensource Automated License Plate Recognition [http://www.openalpr.com]
 *
 * This file is part of OpenAlpr.
 *
 * OpenAlpr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License
 * version 3 as published by the Free Software Foundation
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <sys/stat.h>
#include "support/filesystem.h"
#include "../tclap/CmdLine.h"

using namespace std;
using namespace cv;
using namespace alpr;

// Takes a directory full of single char images, and plops them on a big tif files
// Also creates a box file so Tesseract can recognize it
int main( int argc, const char** argv )
{
  string inDir;
  int tile_width;
  int tile_height;

  TCLAP::CmdLine cmd("OpenAlpr OCR Training Prep Utility", ' ', "1.0.0");

  TCLAP::UnlabeledValueArg<std::string>  inputDirArg( "input_dir", "Folder containing individual character images", true, "", "input_dir_path"  );

  TCLAP::ValueArg<int> tileWidthArg("","tile_width","Width (in pixels) for each character tile.  Default=50",false, 50 ,"tile_width_px");
  TCLAP::ValueArg<int> tileHeightArg("","tile_height","Height (in pixels) for each character tile.  Default=60",false, 60 ,"tile_height_px");

  try
  {
    cmd.add( inputDirArg );
    cmd.add( tileWidthArg );
    cmd.add( tileHeightArg );

    if (cmd.parse( argc, argv ) == false)
    {
      // Error occured while parsing.  Exit now.
      return 1;
    }

    inDir = inputDirArg.getValue();
    tile_width = tileWidthArg.getValue();
    tile_height = tileHeightArg.getValue();

  }
  catch (TCLAP::ArgException &e)    // catch any exceptions
  {
    std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
    return 1;
  }

  if (DirectoryExists(inDir.c_str()) == false)
  {
    printf("Input dir does not exist\n");
    return 1;
  }

  const int CHAR_PADDING_HORIZONTAL = 0;
  const int CHAR_PADDING_VERTICAL = 0;

  const int X_OFFSET = 5;
  const int Y_OFFSET = 5;

  const int PAGE_MARGIN_X = 70;
  const int PAGE_MARGIN_Y = 70;
  const int HORIZONTAL_RESOLUTION = 3500;
  const int MAX_VERTICAL_RESOLUTION = 6000; // Maximum vertical size before chopping into additional pages.

  const int TILE_WIDTH = tile_width;
  const int TILE_HEIGHT = tile_height;
  const int CHAR_HORIZ_OFFSET = 40;
  const int CHAR_VERT_OFFSET = 48;

  const int FIXED_CHAR_HEIGHT = 40; // RESIZE all characters to this height

  vector<string> files = getFilesInDir(inDir.c_str());

  sort( files.begin(), files.end(), stringCompare );

  for (int i = 0; i< files.size(); i++)
  {
    if (hasEnding(files[i], ".png") || hasEnding(files[i], ".jpg"))
    {

    }
    else
    {
      std::cerr << "Non-image file detected in this directory.  This must be removed first" << std::endl;
      return 1;
    }
  }

  int tiles_per_row = ((float) (HORIZONTAL_RESOLUTION - (PAGE_MARGIN_X * 2))) / ((float) TILE_WIDTH);
  int lines = files.size() / (tiles_per_row);
  int vertical_resolution = (lines * TILE_HEIGHT) + (PAGE_MARGIN_Y * 3) ;
  cout << tiles_per_row <<   " : " << vertical_resolution << endl;

  Mat bigTif = Mat::zeros(Size(HORIZONTAL_RESOLUTION, vertical_resolution), CV_8U);
  bitwise_not(bigTif, bigTif);

  stringstream boxFileOut;

  for (int i = 0; i< files.size(); i++)
  {
    int col = i % tiles_per_row;
    int line = i / tiles_per_row;

    int xPos = (col * TILE_WIDTH) + PAGE_MARGIN_X;
    int yPos = (line * TILE_HEIGHT) + PAGE_MARGIN_Y;

    if (hasEnding(files[i], ".png") || hasEnding(files[i], ".jpg"))
    {
      string fullpath = inDir + "/" + files[i];

      cout << "Processing file: " << (i + 1) << " of " << files.size() << " (" << files[i] << ")" << endl;

      char charcode = files[i][0];

      Mat characterImg = imread(fullpath);

      Mat charImgCopy = Mat::zeros(Size(150, 150), characterImg.type());
      bitwise_not(charImgCopy, charImgCopy);

      characterImg.copyTo(charImgCopy(Rect(X_OFFSET, Y_OFFSET, characterImg.cols, characterImg.rows)));
      cvtColor(charImgCopy, charImgCopy, CV_BGR2GRAY);
      bitwise_not(charImgCopy, charImgCopy);

      vector<vector<Point> > contours;

      //imshow("copy", charImgCopy);
      findContours(charImgCopy, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

      float minHeightPercent = 0.35;
      int minHeight = (int) (((float) characterImg.rows) * minHeightPercent);

      vector<Rect> tallEnoughRects;
      for (int c = 0; c < contours.size(); c++)
      {
        Rect tmpRect = boundingRect(contours[c]);
        if (tmpRect.height > minHeight)
          tallEnoughRects.push_back( tmpRect );
      }

      int xMin = 9999999, xMax = 0, yMin = 9999999, yMax = 0;
      // Combine all the "tall enough" rectangles into one super rectangle
      for (int r = 0; r < tallEnoughRects.size(); r++)
      {
        if (tallEnoughRects[r].x < xMin)
          xMin = tallEnoughRects[r].x;
        if (tallEnoughRects[r].y < yMin)
          yMin = tallEnoughRects[r].y;
        if (tallEnoughRects[r].x + tallEnoughRects[r].width > xMax)
          xMax = tallEnoughRects[r].x + tallEnoughRects[r].width;
        if (tallEnoughRects[r].y + tallEnoughRects[r].height > yMax)
          yMax = tallEnoughRects[r].y + tallEnoughRects[r].height;
      }

      Rect tallestRect(xMin, yMin, xMax - xMin, yMax - yMin);

      //cout << tallestRect.x << ":" << tallestRect.y << " -- " << tallestRect.width << ":" << tallestRect.height << endl;

      Rect cropRect(0, tallestRect.y - Y_OFFSET, tallestRect.width, tallestRect.height);

      //cout << "Cropped: " << cropRect.x << ":" << cropRect.y << " -- " << cropRect.width << ":" << cropRect.height << endl;
      Mat cropped(characterImg, cropRect);
      cvtColor(cropped, cropped, CV_BGR2GRAY);

      Rect destinationRect(xPos + (CHAR_HORIZ_OFFSET - TILE_WIDTH), yPos + (CHAR_VERT_OFFSET - TILE_HEIGHT + (TILE_HEIGHT - tallestRect.height)), tallestRect.width, tallestRect.height);

      //cout << "1" << endl;

      cropped.copyTo(bigTif(destinationRect));

      int x1 = destinationRect.x - CHAR_PADDING_HORIZONTAL;
      int y1 = (vertical_resolution - destinationRect.y - destinationRect.height) - CHAR_PADDING_VERTICAL;
      int x2 = (destinationRect.x + destinationRect.width) + CHAR_PADDING_HORIZONTAL;
      int y2 = (vertical_resolution - destinationRect.y) + CHAR_PADDING_VERTICAL;
      //0 70 5602 85 5636 0
      boxFileOut << charcode << " " << x1 << " " << y1 << " ";
      boxFileOut << x2 << " " << y2 ;
      boxFileOut << " 0" << endl;

      //rectangle(characterImg, tallestRect, Scalar(0, 255, 0));
      //imshow("characterImg", cropped);

      waitKey(2);
    }
  }

  imwrite("combined.tif", bigTif);
  ofstream boxFile("combined.box", std::ios::out);
  boxFile << boxFileOut.str();

}
<commit_msg>Added unicode support in prepcharsfortraining<commit_after>/*
 * Copyright (c) 2015 New Designs Unlimited, LLC
 * Opensource Automated License Plate Recognition [http://www.openalpr.com]
 *
 * This file is part of OpenAlpr.
 *
 * OpenAlpr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License
 * version 3 as published by the Free Software Foundation
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <sys/stat.h>
#include "support/filesystem.h"
#include "../tclap/CmdLine.h"
#include "support/utf8.h"

using namespace std;
using namespace cv;
using namespace alpr;

// Takes a directory full of single char images, and plops them on a big tif files
// Also creates a box file so Tesseract can recognize it
int main( int argc, const char** argv )
{
  string inDir;
  int tile_width;
  int tile_height;

  TCLAP::CmdLine cmd("OpenAlpr OCR Training Prep Utility", ' ', "1.0.0");

  TCLAP::UnlabeledValueArg<std::string>  inputDirArg( "input_dir", "Folder containing individual character images", true, "", "input_dir_path"  );

  TCLAP::ValueArg<int> tileWidthArg("","tile_width","Width (in pixels) for each character tile.  Default=50",false, 50 ,"tile_width_px");
  TCLAP::ValueArg<int> tileHeightArg("","tile_height","Height (in pixels) for each character tile.  Default=60",false, 60 ,"tile_height_px");

  try
  {
    cmd.add( inputDirArg );
    cmd.add( tileWidthArg );
    cmd.add( tileHeightArg );

    if (cmd.parse( argc, argv ) == false)
    {
      // Error occured while parsing.  Exit now.
      return 1;
    }

    inDir = inputDirArg.getValue();
    tile_width = tileWidthArg.getValue();
    tile_height = tileHeightArg.getValue();

  }
  catch (TCLAP::ArgException &e)    // catch any exceptions
  {
    std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
    return 1;
  }

  if (DirectoryExists(inDir.c_str()) == false)
  {
    printf("Input dir does not exist\n");
    return 1;
  }

  const int CHAR_PADDING_HORIZONTAL = 0;
  const int CHAR_PADDING_VERTICAL = 0;

  const int X_OFFSET = 5;
  const int Y_OFFSET = 5;

  const int PAGE_MARGIN_X = 70;
  const int PAGE_MARGIN_Y = 70;
  const int HORIZONTAL_RESOLUTION = 3500;
  const int MAX_VERTICAL_RESOLUTION = 6000; // Maximum vertical size before chopping into additional pages.

  const int TILE_WIDTH = tile_width;
  const int TILE_HEIGHT = tile_height;
  const int CHAR_HORIZ_OFFSET = 40;
  const int CHAR_VERT_OFFSET = 48;

  const int FIXED_CHAR_HEIGHT = 40; // RESIZE all characters to this height

  vector<string> files = getFilesInDir(inDir.c_str());

  sort( files.begin(), files.end(), stringCompare );

  for (int i = 0; i< files.size(); i++)
  {
    if (hasEnding(files[i], ".png") || hasEnding(files[i], ".jpg"))
    {

    }
    else
    {
      std::cerr << "Non-image file detected in this directory.  This must be removed first" << std::endl;
      return 1;
    }
  }

  int tiles_per_row = ((float) (HORIZONTAL_RESOLUTION - (PAGE_MARGIN_X * 2))) / ((float) TILE_WIDTH);
  int lines = files.size() / (tiles_per_row);
  int vertical_resolution = (lines * TILE_HEIGHT) + (PAGE_MARGIN_Y * 3) ;
  cout << tiles_per_row <<   " : " << vertical_resolution << endl;

  Mat bigTif = Mat::zeros(Size(HORIZONTAL_RESOLUTION, vertical_resolution), CV_8U);
  bitwise_not(bigTif, bigTif);

  stringstream boxFileOut;

  for (int i = 0; i< files.size(); i++)
  {
    int col = i % tiles_per_row;
    int line = i / tiles_per_row;

    int xPos = (col * TILE_WIDTH) + PAGE_MARGIN_X;
    int yPos = (line * TILE_HEIGHT) + PAGE_MARGIN_Y;

    if (hasEnding(files[i], ".png") || hasEnding(files[i], ".jpg"))
    {
      string fullpath = inDir + "/" + files[i];

      cout << "Processing file: " << (i + 1) << " of " << files.size() << " (" << files[i] << ")" << endl;

      string::iterator utf_iterator = files[i].begin();
      int cp = utf8::next(utf_iterator, files[i].end());
      string charcode = utf8chr(cp);

      Mat characterImg = imread(fullpath);

      Mat charImgCopy = Mat::zeros(Size(150, 150), characterImg.type());
      bitwise_not(charImgCopy, charImgCopy);

      characterImg.copyTo(charImgCopy(Rect(X_OFFSET, Y_OFFSET, characterImg.cols, characterImg.rows)));
      cvtColor(charImgCopy, charImgCopy, CV_BGR2GRAY);
      bitwise_not(charImgCopy, charImgCopy);

      vector<vector<Point> > contours;

      //imshow("copy", charImgCopy);
      findContours(charImgCopy, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

      float minHeightPercent = 0.35;
      int minHeight = (int) (((float) characterImg.rows) * minHeightPercent);

      vector<Rect> tallEnoughRects;
      for (int c = 0; c < contours.size(); c++)
      {
        Rect tmpRect = boundingRect(contours[c]);
        if (tmpRect.height > minHeight)
          tallEnoughRects.push_back( tmpRect );
      }

      int xMin = 9999999, xMax = 0, yMin = 9999999, yMax = 0;
      // Combine all the "tall enough" rectangles into one super rectangle
      for (int r = 0; r < tallEnoughRects.size(); r++)
      {
        if (tallEnoughRects[r].x < xMin)
          xMin = tallEnoughRects[r].x;
        if (tallEnoughRects[r].y < yMin)
          yMin = tallEnoughRects[r].y;
        if (tallEnoughRects[r].x + tallEnoughRects[r].width > xMax)
          xMax = tallEnoughRects[r].x + tallEnoughRects[r].width;
        if (tallEnoughRects[r].y + tallEnoughRects[r].height > yMax)
          yMax = tallEnoughRects[r].y + tallEnoughRects[r].height;
      }

      Rect tallestRect(xMin, yMin, xMax - xMin, yMax - yMin);

      //cout << tallestRect.x << ":" << tallestRect.y << " -- " << tallestRect.width << ":" << tallestRect.height << endl;

      Rect cropRect(0, tallestRect.y - Y_OFFSET, tallestRect.width, tallestRect.height);

      //cout << "Cropped: " << cropRect.x << ":" << cropRect.y << " -- " << cropRect.width << ":" << cropRect.height << endl;
      Mat cropped(characterImg, cropRect);
      cvtColor(cropped, cropped, CV_BGR2GRAY);

      Rect destinationRect(xPos + (CHAR_HORIZ_OFFSET - TILE_WIDTH), yPos + (CHAR_VERT_OFFSET - TILE_HEIGHT + (TILE_HEIGHT - tallestRect.height)), tallestRect.width, tallestRect.height);

      //cout << "1" << endl;

      cropped.copyTo(bigTif(destinationRect));

      int x1 = destinationRect.x - CHAR_PADDING_HORIZONTAL;
      int y1 = (vertical_resolution - destinationRect.y - destinationRect.height) - CHAR_PADDING_VERTICAL;
      int x2 = (destinationRect.x + destinationRect.width) + CHAR_PADDING_HORIZONTAL;
      int y2 = (vertical_resolution - destinationRect.y) + CHAR_PADDING_VERTICAL;
      //0 70 5602 85 5636 0
      boxFileOut << charcode << " " << x1 << " " << y1 << " ";
      boxFileOut << x2 << " " << y2 ;
      boxFileOut << " 0" << endl;

      //rectangle(characterImg, tallestRect, Scalar(0, 255, 0));
      //imshow("characterImg", cropped);

      waitKey(2);
    }
  }

  imwrite("combined.tif", bigTif);
  ofstream boxFile("combined.box", std::ios::out);
  boxFile << boxFileOut.str();

}
<|endoftext|>


<commit_before>//=====================================================================//
/*! @file
	@brief  player クラス
	@author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include "core/glcore.hpp"
#include "gl_fw/glutils.hpp"
#include "effv_main.hpp"

namespace app {

	void effv_main::init_effekseer_(const vtx::spos& size)
	{
		// 描画用インスタンスの生成
		renderer_ = ::EffekseerRendererGL::Renderer::Create( 2000 );

		// エフェクト管理用インスタンスの生成
		manager_ = ::Effekseer::Manager::Create( 2000 );

		// 描画用インスタンスから描画機能を設定
		manager_->SetSpriteRenderer( renderer_->CreateSpriteRenderer() );
		manager_->SetRibbonRenderer( renderer_->CreateRibbonRenderer() );
		manager_->SetRingRenderer( renderer_->CreateRingRenderer() );
		manager_->SetModelRenderer( renderer_->CreateModelRenderer() );

		// 描画用インスタンスからテクスチャの読込機能を設定
		// 独自拡張可能、現在はファイルから読み込んでいる。
		manager_->SetTextureLoader( renderer_->CreateTextureLoader() );
		manager_->SetModelLoader( renderer_->CreateModelLoader() );

		// 音再生用インスタンスの生成
		/// g_sound = EffekseerSound::Sound::Create( 32 );

		// 音再生用インスタンスから再生機能を指定
		/// g_manager->SetSoundPlayer( g_sound->CreateSoundPlayer() );

		// 音再生用インスタンスからサウンドデータの読込機能を設定
		// 独自拡張可能、現在はファイルから読み込んでいる。
		/// g_manager->SetSoundLoader( g_sound->CreateSoundLoader() );

		// 視点位置を確定
		position_ = ::Effekseer::Vector3D( 10.0f, 5.0f, 20.0f );

		// 投影行列を設定
		renderer_->SetProjectionMatrix(
		::Effekseer::Matrix44().PerspectiveFovRH_OpenGL(90.0f / 180.0f * 3.14f, size.x / size.y, 1.0f, 50.0f));

		// カメラ行列を設定
		renderer_->SetCameraMatrix(
			::Effekseer::Matrix44().LookAtRH( position_, ::Effekseer::Vector3D( 0.0f, 0.0f, 0.0f ), ::Effekseer::Vector3D( 0.0f, 1.0f, 0.0f ) ) );
	}

	void effv_main::destroy_effekseer_()
	{
		// エフェクトの停止
		manager_->StopEffect( handle_ );

		// エフェクトの破棄
		ES_SAFE_RELEASE( effect_ );

		// 先にエフェクト管理用インスタンスを破棄
		manager_->Destroy();

		// 次に音再生用インスタンスを破棄
		/// sound_->Destory();

		// 次に描画用インスタンスを破棄
		renderer_->Destory();
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  初期化
	*/
	//-----------------------------------------------------------------//
	void effv_main::initialize()
	{
		gl::core& core = gl::core::get_instance();

		using namespace gui;
		widget_director& wd = director_.at().widget_director_;

		{	// ファイラー・リソース
			widget::param wp(vtx::srect(30, 30, 300, 200));
			widget_filer::param wp_(core.get_current_path());
			filer_ = wd.add_widget<widget_filer>(wp, wp_);
			filer_->enable(false);
		}
		{	// ツールパレット
			widget::param wp(vtx::srect(20, 20, 150, 350));
			widget_frame::param wp_;
			wp_.plate_param_.set_caption(12);
			tools_ = wd.add_widget<widget_frame>(wp, wp_);
			tools_->set_state(gui::widget::state::SIZE_LOCK);
		}
		short h = 12 + 10;
		{	// ファイラー起動ボタン
			widget::param wp(vtx::srect(10, h, 100, 36), tools_);
			h += 40;
			widget_button::param wp_("開く");
			fopen_ = wd.add_widget<widget_button>(wp, wp_);
		}
		{	// Grid、On/Off
			widget::param wp(vtx::srect(10, h, 150, 30), tools_);
			h += 40;
			widget_check::param wp_("Grid", true);
			grid_ = wd.add_widget<widget_check>(wp, wp_);
		}
		{	// Play ボタン
			widget::param wp(vtx::srect(10, h, 100, 36), tools_);
			h += 40;
			widget_button::param wp_("Play");
			play_ = wd.add_widget<widget_button>(wp, wp_);
		}
		{	// Loop、On/Off
			widget::param wp(vtx::srect(10, h, 150, 30), tools_);
			h += 40;
			widget_check::param wp_("Loop", true);
			loop_ = wd.add_widget<widget_check>(wp, wp_);
		}

		init_effekseer_(core.get_rect().size);

		// プリファレンスの取得
		sys::preference& pre = director_.at().preference_;
		if(filer_) {
			filer_->load(pre);
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  アップデート
	*/
	//-----------------------------------------------------------------//
	void effv_main::update()
	{
		gui::widget_director& wd = director_.at().widget_director_;

		if(fopen_->get_selected()) {
			bool f = filer_->get_state(gui::widget::state::ENABLE);
			filer_->enable(!f);
		}

		/// ファイラー、ファイル選択
		if(filer_id_ != filer_->get_select_file_id()) {
			filer_id_ = filer_->get_select_file_id();
///			std::cout << filer_->get_file() << std::endl;

			// エフェクトの読込
			utils::wstring path;
//			utils::utf8_to_utf16("/Users/hira/glfw3_app/glfw3_app/effv/test.efk", path);
//			utils::utf8_to_utf16("/Users/hira/glfw3_app/glfw3_app/effv/dmg_inferno_ek.efk", path);
			utils::utf8_to_utf16(filer_->get_file(), path);
			effect_ = Effekseer::Effect::Create(manager_, path.c_str());
			if(effect_ == nullptr) {
				std::cout << "Can't open effekseer file..." << std::endl;
			} else {
				// エフェクトの再生
				if(manager_) {
					handle_ = manager_->Play(effect_, 0, 0, 0 );
				}
			}
		}

		// アニメーションの再生
		if(loop_->get_check()) {

		}
		if(play_->get_selected()) {
			if(manager_) {
				handle_ = manager_->Play(effect_, 0, 0, 0 );
			}
		}

		if(!wd.update()) {
			camera_.update();
		}

		// エフェクトの移動処理を行う
		if(manager_ && handle_ >= 0) {
			manager_->SetScale(handle_, 5.0f, 5.0f, 5.0f);
///			manager_->AddLocation( handle_, ::Effekseer::Vector3D( 0.2f, 0.0f, 0.0f ) );
			manager_->Update();
		}

	}

	//-----------------------------------------------------------------//
	/*!
		@brief  レンダリング
	*/
	//-----------------------------------------------------------------//
	void effv_main::render()
	{
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
		gl::glColor(img::rgbaf(1.0f));

		camera_.service();

		if(grid_->get_check()) {
			glDisable(GL_TEXTURE_2D);
			glEnable(GL_LINE_SMOOTH);
			glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
			glEnable(GL_BLEND);
			glEnable(GL_DEPTH_TEST);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			gl::draw_grid(vtx::fpos(-10.0f), vtx::fpos(10.0f), vtx::fpos(1.0f));
			glDisable(GL_LINE_SMOOTH);
			glDisable(GL_BLEND);
		}

///		light_.enable(false);

		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);
		glDisable(GL_DEPTH_TEST);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		// エフェクトの描画開始処理を行う。
		if(manager_) {
			renderer_->BeginRendering();

			// エフェクトの描画を行う。
			manager_->Draw();
		}
			// エフェクトの描画終了処理を行う。
		if(renderer_) {
			renderer_->EndRendering();
		}

		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);
		glDisable(GL_DEPTH_TEST);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		director_.at().widget_director_.service();
		director_.at().widget_director_.render();
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  廃棄
	*/
	//-----------------------------------------------------------------//
	void effv_main::destroy()
	{
		sys::preference& pre = director_.at().preference_;
		if(filer_) {
			filer_->save(pre);
		}
	}
}
<commit_msg>srect to irect<commit_after>//=====================================================================//
/*! @file
	@brief  player クラス
	@author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include "core/glcore.hpp"
#include "gl_fw/glutils.hpp"
#include "effv_main.hpp"

namespace app {

	void effv_main::init_effekseer_(const vtx::spos& size)
	{
		// 描画用インスタンスの生成
		renderer_ = ::EffekseerRendererGL::Renderer::Create( 2000 );

		// エフェクト管理用インスタンスの生成
		manager_ = ::Effekseer::Manager::Create( 2000 );

		// 描画用インスタンスから描画機能を設定
		manager_->SetSpriteRenderer( renderer_->CreateSpriteRenderer() );
		manager_->SetRibbonRenderer( renderer_->CreateRibbonRenderer() );
		manager_->SetRingRenderer( renderer_->CreateRingRenderer() );
		manager_->SetModelRenderer( renderer_->CreateModelRenderer() );

		// 描画用インスタンスからテクスチャの読込機能を設定
		// 独自拡張可能、現在はファイルから読み込んでいる。
		manager_->SetTextureLoader( renderer_->CreateTextureLoader() );
		manager_->SetModelLoader( renderer_->CreateModelLoader() );

		// 音再生用インスタンスの生成
		/// g_sound = EffekseerSound::Sound::Create( 32 );

		// 音再生用インスタンスから再生機能を指定
		/// g_manager->SetSoundPlayer( g_sound->CreateSoundPlayer() );

		// 音再生用インスタンスからサウンドデータの読込機能を設定
		// 独自拡張可能、現在はファイルから読み込んでいる。
		/// g_manager->SetSoundLoader( g_sound->CreateSoundLoader() );

		// 視点位置を確定
		position_ = ::Effekseer::Vector3D( 10.0f, 5.0f, 20.0f );

		// 投影行列を設定
		renderer_->SetProjectionMatrix(
		::Effekseer::Matrix44().PerspectiveFovRH_OpenGL(90.0f / 180.0f * 3.14f, size.x / size.y, 1.0f, 50.0f));

		// カメラ行列を設定
		renderer_->SetCameraMatrix(
			::Effekseer::Matrix44().LookAtRH( position_, ::Effekseer::Vector3D( 0.0f, 0.0f, 0.0f ), ::Effekseer::Vector3D( 0.0f, 1.0f, 0.0f ) ) );
	}

	void effv_main::destroy_effekseer_()
	{
		// エフェクトの停止
		manager_->StopEffect( handle_ );

		// エフェクトの破棄
		ES_SAFE_RELEASE( effect_ );

		// 先にエフェクト管理用インスタンスを破棄
		manager_->Destroy();

		// 次に音再生用インスタンスを破棄
		/// sound_->Destory();

		// 次に描画用インスタンスを破棄
		renderer_->Destory();
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  初期化
	*/
	//-----------------------------------------------------------------//
	void effv_main::initialize()
	{
		gl::core& core = gl::core::get_instance();

		using namespace gui;
		widget_director& wd = director_.at().widget_director_;

		{	// ファイラー・リソース
			widget::param wp(vtx::irect(30, 30, 300, 200));
			widget_filer::param wp_(core.get_current_path());
			filer_ = wd.add_widget<widget_filer>(wp, wp_);
			filer_->enable(false);
		}
		{	// ツールパレット
			widget::param wp(vtx::irect(20, 20, 150, 350));
			widget_frame::param wp_;
			wp_.plate_param_.set_caption(12);
			tools_ = wd.add_widget<widget_frame>(wp, wp_);
			tools_->set_state(gui::widget::state::SIZE_LOCK);
		}
		short h = 12 + 10;
		{	// ファイラー起動ボタン
			widget::param wp(vtx::irect(10, h, 100, 36), tools_);
			h += 40;
			widget_button::param wp_("開く");
			fopen_ = wd.add_widget<widget_button>(wp, wp_);
		}
		{	// Grid、On/Off
			widget::param wp(vtx::irect(10, h, 150, 30), tools_);
			h += 40;
			widget_check::param wp_("Grid", true);
			grid_ = wd.add_widget<widget_check>(wp, wp_);
		}
		{	// Play ボタン
			widget::param wp(vtx::irect(10, h, 100, 36), tools_);
			h += 40;
			widget_button::param wp_("Play");
			play_ = wd.add_widget<widget_button>(wp, wp_);
		}
		{	// Loop、On/Off
			widget::param wp(vtx::irect(10, h, 150, 30), tools_);
			h += 40;
			widget_check::param wp_("Loop", true);
			loop_ = wd.add_widget<widget_check>(wp, wp_);
		}

		init_effekseer_(core.get_rect().size);

		// プリファレンスの取得
		sys::preference& pre = director_.at().preference_;
		if(filer_) {
			filer_->load(pre);
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  アップデート
	*/
	//-----------------------------------------------------------------//
	void effv_main::update()
	{
		gui::widget_director& wd = director_.at().widget_director_;

		if(fopen_->get_selected()) {
			bool f = filer_->get_state(gui::widget::state::ENABLE);
			filer_->enable(!f);
		}

		/// ファイラー、ファイル選択
		if(filer_id_ != filer_->get_select_file_id()) {
			filer_id_ = filer_->get_select_file_id();
///			std::cout << filer_->get_file() << std::endl;

			// エフェクトの読込
			utils::wstring path;
//			utils::utf8_to_utf16("/Users/hira/glfw3_app/glfw3_app/effv/test.efk", path);
//			utils::utf8_to_utf16("/Users/hira/glfw3_app/glfw3_app/effv/dmg_inferno_ek.efk", path);
			utils::utf8_to_utf16(filer_->get_file(), path);
			effect_ = Effekseer::Effect::Create(manager_, path.c_str());
			if(effect_ == nullptr) {
				std::cout << "Can't open effekseer file..." << std::endl;
			} else {
				// エフェクトの再生
				if(manager_) {
					handle_ = manager_->Play(effect_, 0, 0, 0 );
				}
			}
		}

		// アニメーションの再生
		if(loop_->get_check()) {

		}
		if(play_->get_selected()) {
			if(manager_) {
				handle_ = manager_->Play(effect_, 0, 0, 0 );
			}
		}

		if(!wd.update()) {
			camera_.update();
		}

		// エフェクトの移動処理を行う
		if(manager_ && handle_ >= 0) {
			manager_->SetScale(handle_, 5.0f, 5.0f, 5.0f);
///			manager_->AddLocation( handle_, ::Effekseer::Vector3D( 0.2f, 0.0f, 0.0f ) );
			manager_->Update();
		}

	}

	//-----------------------------------------------------------------//
	/*!
		@brief  レンダリング
	*/
	//-----------------------------------------------------------------//
	void effv_main::render()
	{
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
		gl::glColor(img::rgbaf(1.0f));

		camera_.service();

		if(grid_->get_check()) {
			glDisable(GL_TEXTURE_2D);
			glEnable(GL_LINE_SMOOTH);
			glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
			glEnable(GL_BLEND);
			glEnable(GL_DEPTH_TEST);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			gl::draw_grid(vtx::fpos(-10.0f), vtx::fpos(10.0f), vtx::fpos(1.0f));
			glDisable(GL_LINE_SMOOTH);
			glDisable(GL_BLEND);
		}

///		light_.enable(false);

		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);
		glDisable(GL_DEPTH_TEST);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		// エフェクトの描画開始処理を行う。
		if(manager_) {
			renderer_->BeginRendering();

			// エフェクトの描画を行う。
			manager_->Draw();
		}
			// エフェクトの描画終了処理を行う。
		if(renderer_) {
			renderer_->EndRendering();
		}

		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);
		glDisable(GL_DEPTH_TEST);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		director_.at().widget_director_.service();
		director_.at().widget_director_.render();
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  廃棄
	*/
	//-----------------------------------------------------------------//
	void effv_main::destroy()
	{
		sys::preference& pre = director_.at().preference_;
		if(filer_) {
			filer_->save(pre);
		}
	}
}
<|endoftext|>


<commit_before>#include "DicomGeometryBuilder.hh"

#include <stdexcept>

#include <G4LogicalVolume.hh>
#include <G4Box.hh>
#include <G4Material.hh>
#include <G4NistManager.hh>
#include <G4PVPlacement.hh>
#include <G4PVReplica.hh>
#include <G4PVParameterised.hh>
#include <G4VisAttributes.hh>
#include <globals.hh>

#include "Configuration.hh"

#include "VMaterialDatabase.hh"
#include "DicomData.hh"
#include "dicomConfiguration.hh"
#include "VoxelParameterisation.hh"

using namespace g4dicom;
using namespace std;
using namespace g4;

// See http://nipy.org/nibabel/dicom/dicom_orientation.html

void DicomGeometryBuilder::ConfigurationChanged(const std::string& key)
{
    if (key == VIS_SHOW_VOXELS)
    {
        bool val = Configuration::GetValue<int>(key);
        SetVoxelsVisible(val);
    }
    else if (key == PHANTOM_CENTER_X)
    {
        double val = Configuration::GetValue<double>(key) * mm;
        G4ThreeVector newCenter(val, _phantomCenter.getY(), _phantomCenter.getZ());
        SetPhantomCenter(newCenter);
    }
    else if (key == PHANTOM_CENTER_Y)
    {
        double val = Configuration::GetValue<double>(key) * mm;
        G4ThreeVector newCenter(_phantomCenter.getX(), val, _phantomCenter.getZ());
        SetPhantomCenter(newCenter);
    }
    else if (key == PHANTOM_CENTER_Z)
    {
        double val = Configuration::GetValue<double>(key) * mm;
        G4ThreeVector newCenter(_phantomCenter.getX(), _phantomCenter.getY(), val);
        SetPhantomCenter(newCenter);
    }
}

void DicomGeometryBuilder::SetVoxelsVisible(bool value)
{
    _voxelsVisible = value;
    Configuration::SetValue(VIS_SHOW_VOXELS, value);
}

void DicomGeometryBuilder::SetPhantomCenter(const G4ThreeVector& position)
{
    bool positionChanged = (_phantomCenter != position);
    if (positionChanged)
    {
        _phantomCenter = position;
        Configuration::SetValue(PHANTOM_CENTER_X, position.getX() / mm);
        Configuration::SetValue(PHANTOM_CENTER_Y, position.getX() / mm);
        Configuration::SetValue(PHANTOM_CENTER_Z, position.getX() / mm);

        if (_physContainer)
        {
            _physContainer->SetTranslation(_phantomCenter); // Is this ok?
            GeometryChanged();
        }
    }
}

void DicomGeometryBuilder::BuildGeometry(G4LogicalVolume* logWorld)
{
    if (!_data)
    {
        throw runtime_error("Cannot build geometry without DICOM data.");
    }
    if (!_materialDatabase)
    {
        throw runtime_error("Cannot build geometry without material data.");
    }
    vector<int> dims = _data->GetDimensions();
    G4cout << "Building DICOM voxel geometry of "
        << dims[0] << " x " << dims[1] << " x " << dims[2]
        << "..." << G4endl;

    vector<double> totalSize = _data->GetTotalSize();
    G4cout << "Total size is " << totalSize[0]
        << " x " << totalSize[1] << " x " << totalSize[2] << " mm."
        << G4endl;

    G4LogicalVolume* logContainer = BuildLogicalVolume();
    _physContainer =
        new G4PVPlacement(0,                // Rotation
            _phantomCenter,                 // Position
            logContainer,                   // The logic volume
            "phantomContainer",             // Name
            logWorld,                       // Mother
            false,                          // No op. bool.
            1);                             // Copy number
}

G4LogicalVolume *DicomGeometryBuilder::BuildLogicalVolume()
{
    vector<double> voxelSize = _data->GetVoxelSize();
    vector<double> totalSize = _data->GetTotalSize();
    vector<int> dims = _data->GetDimensions();

    // Fill everything with air
    G4Material* air = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR");

    // The container
    G4String containerName("voxelContainer");
    G4VSolid* solContainer =
        new G4Box(containerName, totalSize[0]/2, totalSize[1]/2, totalSize[2]/2);
    G4LogicalVolume* logContainer =
        new G4LogicalVolume(solContainer, air, containerName);

    G4String xReplicaName("voxelX");
    G4String yReplicaName("voxelY");
    G4String zReplicaName("voxelZ");

    // Solids
    G4VSolid* solXReplica =
        new G4Box(xReplicaName, voxelSize[0]/2, totalSize[1]/2, totalSize[2]/2);
    G4VSolid* solYReplica =
        new G4Box(yReplicaName, voxelSize[0]/2, voxelSize[1]/2, totalSize[2]/2);
    G4VSolid* solZVoxel =
        new G4Box(zReplicaName, voxelSize[0]/2, voxelSize[1]/2, voxelSize[2]/2);

    // Logical volumes
    G4LogicalVolume* logXReplica =
        new G4LogicalVolume(solXReplica, air, xReplicaName);
    G4LogicalVolume* logYReplica =
        new G4LogicalVolume(solYReplica, air, yReplicaName);
    G4LogicalVolume* logZVoxel =
        new G4LogicalVolume(solZVoxel, air, zReplicaName);

    logXReplica->SetVisAttributes(G4VisAttributes::Invisible);
    logYReplica->SetVisAttributes(G4VisAttributes::Invisible);
    if (!_voxelsVisible)
    {
        logZVoxel->SetVisAttributes(G4VisAttributes::Invisible);
    }

    // Place physical volumes for x&y
    new G4PVReplica(xReplicaName, logXReplica, logContainer, kXAxis, dims[0], voxelSize[0]);
    new G4PVReplica(yReplicaName, logYReplica, logXReplica, kYAxis, dims[1], voxelSize[1]);

    // Place physical volume with parameterisation for z
    VoxelParameterisation* voxelParam = new VoxelParameterisation(_materialDatabase, _data);
    new G4PVParameterised(zReplicaName,
                          logZVoxel,
                          logYReplica,
                          kZAxis,
                          dims[2],
                          voxelParam);

    // Physical volumes
    return logContainer;
}

DicomGeometryBuilder::DicomGeometryBuilder()
    : _data(0), _materialDatabase(0), _physContainer(0)
{
    _phantomCenter.setX(Configuration::GetValue(PHANTOM_CENTER_X, 0.));
    _phantomCenter.setY(Configuration::GetValue(PHANTOM_CENTER_Y, 0.));
    _phantomCenter.setZ(Configuration::GetValue(PHANTOM_CENTER_Z, 0.));
}

DicomGeometryBuilder::~DicomGeometryBuilder()
{
    // _data is deleted by the originating DicomReader.
}
<commit_msg>Fix: DicomGeometryBuilder::SetPhantomCenter saves wrong data.<commit_after>#include "DicomGeometryBuilder.hh"

#include <stdexcept>

#include <G4LogicalVolume.hh>
#include <G4Box.hh>
#include <G4Material.hh>
#include <G4NistManager.hh>
#include <G4PVPlacement.hh>
#include <G4PVReplica.hh>
#include <G4PVParameterised.hh>
#include <G4VisAttributes.hh>
#include <globals.hh>

#include "Configuration.hh"

#include "VMaterialDatabase.hh"
#include "DicomData.hh"
#include "dicomConfiguration.hh"
#include "VoxelParameterisation.hh"

using namespace g4dicom;
using namespace std;
using namespace g4;

// See http://nipy.org/nibabel/dicom/dicom_orientation.html

void DicomGeometryBuilder::ConfigurationChanged(const std::string& key)
{
    if (key == VIS_SHOW_VOXELS)
    {
        bool val = Configuration::GetValue<int>(key);
        SetVoxelsVisible(val);
    }
    else if (key == PHANTOM_CENTER_X)
    {
        double val = Configuration::GetValue<double>(key) * mm;
        G4ThreeVector newCenter(val, _phantomCenter.getY(), _phantomCenter.getZ());
        SetPhantomCenter(newCenter);
    }
    else if (key == PHANTOM_CENTER_Y)
    {
        double val = Configuration::GetValue<double>(key) * mm;
        G4ThreeVector newCenter(_phantomCenter.getX(), val, _phantomCenter.getZ());
        SetPhantomCenter(newCenter);
    }
    else if (key == PHANTOM_CENTER_Z)
    {
        double val = Configuration::GetValue<double>(key) * mm;
        G4ThreeVector newCenter(_phantomCenter.getX(), _phantomCenter.getY(), val);
        SetPhantomCenter(newCenter);
    }
}

void DicomGeometryBuilder::SetVoxelsVisible(bool value)
{
    _voxelsVisible = value;
    Configuration::SetValue(VIS_SHOW_VOXELS, value);
}

void DicomGeometryBuilder::SetPhantomCenter(const G4ThreeVector& position)
{
    bool positionChanged = (_phantomCenter != position);
    if (positionChanged)
    {
        _phantomCenter = position;
        Configuration::SetValue(PHANTOM_CENTER_X, position.getX() / mm);
        Configuration::SetValue(PHANTOM_CENTER_Y, position.getY() / mm);
        Configuration::SetValue(PHANTOM_CENTER_Z, position.getZ() / mm);

        if (_physContainer)
        {
            _physContainer->SetTranslation(_phantomCenter); // Is this ok?
            GeometryChanged();
        }
    }
}

void DicomGeometryBuilder::BuildGeometry(G4LogicalVolume* logWorld)
{
    if (!_data)
    {
        throw runtime_error("Cannot build geometry without DICOM data.");
    }
    if (!_materialDatabase)
    {
        throw runtime_error("Cannot build geometry without material data.");
    }
    vector<int> dims = _data->GetDimensions();
    G4cout << "Building DICOM voxel geometry of "
        << dims[0] << " x " << dims[1] << " x " << dims[2]
        << "..." << G4endl;

    vector<double> totalSize = _data->GetTotalSize();
    G4cout << "Total size is " << totalSize[0]
        << " x " << totalSize[1] << " x " << totalSize[2] << " mm."
        << G4endl;

    G4LogicalVolume* logContainer = BuildLogicalVolume();
    _physContainer =
        new G4PVPlacement(0,                // Rotation
            _phantomCenter,                 // Position
            logContainer,                   // The logic volume
            "phantomContainer",             // Name
            logWorld,                       // Mother
            false,                          // No op. bool.
            1);                             // Copy number
}

G4LogicalVolume *DicomGeometryBuilder::BuildLogicalVolume()
{
    vector<double> voxelSize = _data->GetVoxelSize();
    vector<double> totalSize = _data->GetTotalSize();
    vector<int> dims = _data->GetDimensions();

    // Fill everything with air
    G4Material* air = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR");

    // The container
    G4String containerName("voxelContainer");
    G4VSolid* solContainer =
        new G4Box(containerName, totalSize[0]/2, totalSize[1]/2, totalSize[2]/2);
    G4LogicalVolume* logContainer =
        new G4LogicalVolume(solContainer, air, containerName);

    G4String xReplicaName("voxelX");
    G4String yReplicaName("voxelY");
    G4String zReplicaName("voxelZ");

    // Solids
    G4VSolid* solXReplica =
        new G4Box(xReplicaName, voxelSize[0]/2, totalSize[1]/2, totalSize[2]/2);
    G4VSolid* solYReplica =
        new G4Box(yReplicaName, voxelSize[0]/2, voxelSize[1]/2, totalSize[2]/2);
    G4VSolid* solZVoxel =
        new G4Box(zReplicaName, voxelSize[0]/2, voxelSize[1]/2, voxelSize[2]/2);

    // Logical volumes
    G4LogicalVolume* logXReplica =
        new G4LogicalVolume(solXReplica, air, xReplicaName);
    G4LogicalVolume* logYReplica =
        new G4LogicalVolume(solYReplica, air, yReplicaName);
    G4LogicalVolume* logZVoxel =
        new G4LogicalVolume(solZVoxel, air, zReplicaName);

    logXReplica->SetVisAttributes(G4VisAttributes::Invisible);
    logYReplica->SetVisAttributes(G4VisAttributes::Invisible);
    if (!_voxelsVisible)
    {
        logZVoxel->SetVisAttributes(G4VisAttributes::Invisible);
    }

    // Place physical volumes for x&y
    new G4PVReplica(xReplicaName, logXReplica, logContainer, kXAxis, dims[0], voxelSize[0]);
    new G4PVReplica(yReplicaName, logYReplica, logXReplica, kYAxis, dims[1], voxelSize[1]);

    // Place physical volume with parameterisation for z
    VoxelParameterisation* voxelParam = new VoxelParameterisation(_materialDatabase, _data);
    new G4PVParameterised(zReplicaName,
                          logZVoxel,
                          logYReplica,
                          kZAxis,
                          dims[2],
                          voxelParam);

    // Physical volumes
    return logContainer;
}

DicomGeometryBuilder::DicomGeometryBuilder()
    : _data(0), _materialDatabase(0), _physContainer(0)
{
    _phantomCenter.setX(Configuration::GetValue(PHANTOM_CENTER_X, 0.));
    _phantomCenter.setY(Configuration::GetValue(PHANTOM_CENTER_Y, 0.));
    _phantomCenter.setZ(Configuration::GetValue(PHANTOM_CENTER_Z, 0.));
}

DicomGeometryBuilder::~DicomGeometryBuilder()
{
    // _data is deleted by the originating DicomReader.
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/

#include "processstep.h"
#include "buildstep.h"
#include "project.h"

#include <coreplugin/ifile.h>

#include <QtCore/QDebug>
#include <QtGui/QFileDialog>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

ProcessStep::ProcessStep(Project *pro)
        : AbstractProcessStep(pro)
{

}

bool ProcessStep::init(const QString &buildConfiguration)
{
    setEnvironment(buildConfiguration, project()->environment(buildConfiguration));
    QVariant wd = value(buildConfiguration, "workingDirectory").toString();
    QString workingDirectory;
    if (!wd.isValid() || wd.toString().isEmpty())
        workingDirectory = "$BUILDDIR";
    else
        workingDirectory = wd.toString();
    setWorkingDirectory(buildConfiguration, workingDirectory.replace("$BUILDDIR", project()->buildDirectory(buildConfiguration)));
    return AbstractProcessStep::init(buildConfiguration);
}

void ProcessStep::run(QFutureInterface<bool> & fi)
{
    return AbstractProcessStep::run(fi);
}

QString ProcessStep::name()
{
    return "projectexplorer.processstep";
}

void ProcessStep::setDisplayName(const QString &name)
{
    setValue("ProjectExplorer.ProcessStep.DisplayName", name);
}

QString ProcessStep::displayName()
{
    QVariant displayName = value("ProjectExplorer.ProcessStep.DisplayName");
    if (displayName.isValid())
        return displayName.toString();
    else
        return tr("Custom Process Step");
}

BuildStepConfigWidget *ProcessStep::createConfigWidget()
{
    return new ProcessStepConfigWidget(this);
}

bool ProcessStep::immutable() const
{
    return false;
}

//*******
// ProcessStepFactory
//*******

ProcessStepFactory::ProcessStepFactory()
{

}

bool ProcessStepFactory::canCreate(const QString &name) const
{
    return name == "projectexplorer.processstep";
}

BuildStep *ProcessStepFactory::create(Project *pro, const QString &name) const
{
    Q_UNUSED(name)
    return new ProcessStep(pro);
}

QStringList ProcessStepFactory::canCreateForProject(Project *pro) const
{
    Q_UNUSED(pro)
    return QStringList()<<"projectexplorer.processstep";
}
QString ProcessStepFactory::displayNameForName(const QString &name) const
{
    Q_UNUSED(name)
    return "Custom Process Step";
}

//*******
// ProcessStepConfigWidget
//*******

ProcessStepConfigWidget::ProcessStepConfigWidget(ProcessStep *step)
        : m_step(step)
{
    m_ui.setupUi(this);
    m_ui.command->setExpectedKind(Core::Utils::PathChooser::File);
    connect(m_ui.command, SIGNAL(changed(QString)),
            this, SLOT(commandLineEditTextEdited()));
    connect(m_ui.workingDirectory, SIGNAL(changed(QString)),
            this, SLOT(workingDirectoryLineEditTextEdited()));

    connect(m_ui.nameLineEdit, SIGNAL(textEdited(const QString&)),
            this, SLOT(nameLineEditTextEdited()));
    connect(m_ui.commandArgumentsLineEdit, SIGNAL(textEdited(const QString&)),
            this, SLOT(commandArgumentsLineEditTextEdited()));
    connect(m_ui.enabledCheckBox, SIGNAL(clicked(bool)),
            this, SLOT(enabledCheckBoxClicked(bool)));

    connect(m_ui.detailsButton, SIGNAL(clicked()),
            this, SLOT(toggleDetails()));

    m_ui.detailsWidget->setVisible(false);
}

void ProcessStepConfigWidget::updateDetails()
{
    m_summaryText = tr("Process Step %1 %2 %3")
                    .arg(m_step->command(m_buildConfiguration),
                         m_step->arguments(m_buildConfiguration).join(" "),
                         m_step->enabled(m_buildConfiguration) ? "" : tr("(disabled)"));
    emit updateSummary();
}

void ProcessStepConfigWidget::toggleDetails()
{
    m_ui.detailsWidget->setVisible(!m_ui.detailsWidget->isVisible());
}

QString ProcessStepConfigWidget::displayName() const
{
    return m_step->name();
}

void ProcessStepConfigWidget::init(const QString &buildConfiguration)
{
    m_buildConfiguration = buildConfiguration;
    if (buildConfiguration != QString::null) {
        m_ui.command->setPath(m_step->command(buildConfiguration));

        QString workingDirectory = m_step->value(buildConfiguration, "workingDirectory").toString();
        if (workingDirectory.isEmpty())
            workingDirectory = "$BUILDDIR";
        m_ui.workingDirectory->setPath(workingDirectory);

        m_ui.commandArgumentsLineEdit->setText(m_step->arguments(buildConfiguration).join(" "));
        m_ui.enabledCheckBox->setChecked(m_step->enabled(buildConfiguration));
    }
    m_ui.nameLineEdit->setText(m_step->displayName());
    updateDetails();
}

QString ProcessStepConfigWidget::summaryText() const
{
    return m_summaryText;
}

void ProcessStepConfigWidget::nameLineEditTextEdited()
{
    m_step->setDisplayName(m_ui.nameLineEdit->text());
}

void ProcessStepConfigWidget::commandLineEditTextEdited()
{
    m_step->setCommand(m_buildConfiguration, m_ui.command->path());
    updateDetails();
}

void ProcessStepConfigWidget::workingDirectoryLineEditTextEdited()
{
    QString wd = m_ui.workingDirectory->path();
    m_step->setValue(m_buildConfiguration, "workingDirectory", wd);
}

void ProcessStepConfigWidget::commandArgumentsLineEditTextEdited()
{
    m_step->setArguments(m_buildConfiguration, m_ui.commandArgumentsLineEdit->text().split(" ",
          QString::SkipEmptyParts));
    updateDetails();
}

void ProcessStepConfigWidget::enabledCheckBoxClicked(bool)
{
    m_step->setEnabled(m_buildConfiguration, m_ui.enabledCheckBox->isChecked());
    updateDetails();
}
<commit_msg>Added possibility to translate "Custom Process Step" item of the combobox in project settings.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/

#include "processstep.h"
#include "buildstep.h"
#include "project.h"

#include <coreplugin/ifile.h>

#include <QtCore/QDebug>
#include <QtGui/QFileDialog>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

ProcessStep::ProcessStep(Project *pro)
        : AbstractProcessStep(pro)
{

}

bool ProcessStep::init(const QString &buildConfiguration)
{
    setEnvironment(buildConfiguration, project()->environment(buildConfiguration));
    QVariant wd = value(buildConfiguration, "workingDirectory").toString();
    QString workingDirectory;
    if (!wd.isValid() || wd.toString().isEmpty())
        workingDirectory = "$BUILDDIR";
    else
        workingDirectory = wd.toString();
    setWorkingDirectory(buildConfiguration, workingDirectory.replace("$BUILDDIR", project()->buildDirectory(buildConfiguration)));
    return AbstractProcessStep::init(buildConfiguration);
}

void ProcessStep::run(QFutureInterface<bool> & fi)
{
    return AbstractProcessStep::run(fi);
}

QString ProcessStep::name()
{
    return "projectexplorer.processstep";
}

void ProcessStep::setDisplayName(const QString &name)
{
    setValue("ProjectExplorer.ProcessStep.DisplayName", name);
}

QString ProcessStep::displayName()
{
    QVariant displayName = value("ProjectExplorer.ProcessStep.DisplayName");
    if (displayName.isValid())
        return displayName.toString();
    else
        return tr("Custom Process Step");
}

BuildStepConfigWidget *ProcessStep::createConfigWidget()
{
    return new ProcessStepConfigWidget(this);
}

bool ProcessStep::immutable() const
{
    return false;
}

//*******
// ProcessStepFactory
//*******

ProcessStepFactory::ProcessStepFactory()
{

}

bool ProcessStepFactory::canCreate(const QString &name) const
{
    return name == "projectexplorer.processstep";
}

BuildStep *ProcessStepFactory::create(Project *pro, const QString &name) const
{
    Q_UNUSED(name)
    return new ProcessStep(pro);
}

QStringList ProcessStepFactory::canCreateForProject(Project *pro) const
{
    Q_UNUSED(pro)
    return QStringList()<<"projectexplorer.processstep";
}
QString ProcessStepFactory::displayNameForName(const QString &name) const
{
    Q_UNUSED(name)
    return ProcessStep::tr("Custom Process Step", "item in combobox");
}

//*******
// ProcessStepConfigWidget
//*******

ProcessStepConfigWidget::ProcessStepConfigWidget(ProcessStep *step)
        : m_step(step)
{
    m_ui.setupUi(this);
    m_ui.command->setExpectedKind(Core::Utils::PathChooser::File);
    connect(m_ui.command, SIGNAL(changed(QString)),
            this, SLOT(commandLineEditTextEdited()));
    connect(m_ui.workingDirectory, SIGNAL(changed(QString)),
            this, SLOT(workingDirectoryLineEditTextEdited()));

    connect(m_ui.nameLineEdit, SIGNAL(textEdited(const QString&)),
            this, SLOT(nameLineEditTextEdited()));
    connect(m_ui.commandArgumentsLineEdit, SIGNAL(textEdited(const QString&)),
            this, SLOT(commandArgumentsLineEditTextEdited()));
    connect(m_ui.enabledCheckBox, SIGNAL(clicked(bool)),
            this, SLOT(enabledCheckBoxClicked(bool)));

    connect(m_ui.detailsButton, SIGNAL(clicked()),
            this, SLOT(toggleDetails()));

    m_ui.detailsWidget->setVisible(false);
}

void ProcessStepConfigWidget::updateDetails()
{
    m_summaryText = tr("Process Step %1 %2 %3")
                    .arg(m_step->command(m_buildConfiguration),
                         m_step->arguments(m_buildConfiguration).join(" "),
                         m_step->enabled(m_buildConfiguration) ? "" : tr("(disabled)"));
    emit updateSummary();
}

void ProcessStepConfigWidget::toggleDetails()
{
    m_ui.detailsWidget->setVisible(!m_ui.detailsWidget->isVisible());
}

QString ProcessStepConfigWidget::displayName() const
{
    return m_step->name();
}

void ProcessStepConfigWidget::init(const QString &buildConfiguration)
{
    m_buildConfiguration = buildConfiguration;
    if (buildConfiguration != QString::null) {
        m_ui.command->setPath(m_step->command(buildConfiguration));

        QString workingDirectory = m_step->value(buildConfiguration, "workingDirectory").toString();
        if (workingDirectory.isEmpty())
            workingDirectory = "$BUILDDIR";
        m_ui.workingDirectory->setPath(workingDirectory);

        m_ui.commandArgumentsLineEdit->setText(m_step->arguments(buildConfiguration).join(" "));
        m_ui.enabledCheckBox->setChecked(m_step->enabled(buildConfiguration));
    }
    m_ui.nameLineEdit->setText(m_step->displayName());
    updateDetails();
}

QString ProcessStepConfigWidget::summaryText() const
{
    return m_summaryText;
}

void ProcessStepConfigWidget::nameLineEditTextEdited()
{
    m_step->setDisplayName(m_ui.nameLineEdit->text());
}

void ProcessStepConfigWidget::commandLineEditTextEdited()
{
    m_step->setCommand(m_buildConfiguration, m_ui.command->path());
    updateDetails();
}

void ProcessStepConfigWidget::workingDirectoryLineEditTextEdited()
{
    QString wd = m_ui.workingDirectory->path();
    m_step->setValue(m_buildConfiguration, "workingDirectory", wd);
}

void ProcessStepConfigWidget::commandArgumentsLineEditTextEdited()
{
    m_step->setArguments(m_buildConfiguration, m_ui.commandArgumentsLineEdit->text().split(" ",
          QString::SkipEmptyParts));
    updateDetails();
}

void ProcessStepConfigWidget::enabledCheckBoxClicked(bool)
{
    m_step->setEnabled(m_buildConfiguration, m_ui.enabledCheckBox->isChecked());
    updateDetails();
}
<|endoftext|>


<commit_before>
<commit_msg>Delete Proj2.cpp<commit_after><|endoftext|>


<commit_before>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>

using namespace std;

int sizeAL[150];
int appearanceL[150][150][2];
int sizeAcm;
int Pos, numWord;

void solve(int lastPosA, int lastWord, int lastPosWord){
	if ((lastPosA == sizeAcm) && (lastWord == numWord)){
		//cout << lastWord << " " << numWord << " \n";
		++Pos;
	}
	else {
		for (int i = 0; i < sizeAL[lastPosA]; i++){

			if (appearanceL[lastPosA][i][2] >= lastWord){

				if ((appearanceL[lastPosA][i][2] == lastWord) && (appearanceL[lastPosA][i][1] <= lastPosWord)){
					continue;
				}
				if (appearanceL[lastPosA][i][2] >(lastWord + 1)){
					continue;
				}

				solve(lastPosA + 1, appearanceL[lastPosA][i][2], appearanceL[lastPosA][i][1]);
			}
		}
	}
}

int main(int argc, char *argv[]){

	int nRestrictedWords;
	string acm, word;
	char str[151];
	string restrictedWords[100];
	bool valid;

	// Lectura y preprocesamiento de cada grupo de casos
	while (1){
		scanf("%d", &nRestrictedWords);

		if (nRestrictedWords == 0){
			break;
		}

		for (int i = 0; i < nRestrictedWords; i++){

			scanf("%150s", &str);
			restrictedWords[i] = str;

		}

		scanf("%150s", &str);
		acm = str;

		scanf("%150s", &str);
		word = str;

		sizeAcm = acm.size();
		numWord = 0;

		memset(sizeAL, 0, sizeof(int) * 150);

		// Lectura y pre procesamiento de cada caso
		while (islower(word[0])){

			valid = true;

			for (int i = 0; i < nRestrictedWords; i++){
				if (!restrictedWords[i].compare(word)){
					valid = false;
					break;
				}
			}

			if (valid){
				for (int i = 0; i < word.size(); i++){
					for (int j = 0; j < sizeAcm; j++){
						if (tolower(acm[j]) == word[i]){
							if (j == 0 && numWord != 0){
								continue;
							}
							appearanceL[j][sizeAL[j]][1] = i;
							appearanceL[j][sizeAL[j]][2] = numWord;
							++sizeAL[j];

						}
					}
				}
			}
			scanf("%150s", &str);
			word = str;

			if (isupper(word[0])){

				Pos = 0;
				for (int k = 0; k < sizeAL[0]; k++){
					solve(1, 0, appearanceL[0][k][1]);
				}

				if (Pos == 0){
					printf("%s is not a valid abbreviation\n", acm.c_str());
				}
				else {
					printf("%s can be formed in %i ways\n", acm.c_str(), Pos);
				}

				acm = word;

				numWord = 0;
				memset(sizeAL, 0, sizeof(int) * 150);
				sizeAcm = acm.size();
				scanf("%150s", &str);
				word = str;
				valid = false;
			}

			if (valid){
				++numWord;
			}

		}

	}
	//while (1){

	//};
}
<commit_msg>Solucion del 1 caliche...<commit_after>#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define inf 1000000000
#define MAXN 151

using namespace std;

int dp[MAXN][MAXN][2];
string abbr, abbreviation;
int abbr_len;
string phrase;
int phrase_len;

int rek(int pos = 0, int abbr_pos = 0, bool took_a_char = false) {
    if (pos == phrase_len) return abbr_pos == abbr_len && took_a_char;
    if (dp[pos][abbr_pos][took_a_char] != -1) return dp[pos][abbr_pos][took_a_char];
    if (phrase[pos] == ' ') {
        if (!took_a_char) return 0;
        else return dp[pos][abbr_pos][took_a_char] = rek(pos+1, abbr_pos, false);
    }
    if (abbr_pos == abbr_len) return dp[pos][abbr_pos][took_a_char] = rek(pos+1, abbr_pos, took_a_char);

    dp[pos][abbr_pos][took_a_char] = rek(pos+1, abbr_pos, took_a_char);
    if (phrase[pos] == abbr[abbr_pos]) {
        dp[pos][abbr_pos][took_a_char] += rek(pos+1, abbr_pos+1, true);
    }

    return dp[pos][abbr_pos][took_a_char];
}

int main() {
    while (true) {
        int t;
        cin >> t;
        if (!t) return 0;

        set<string> insignificant_words;

        string insignificant_word;
        for (int qwertz = 0; qwertz < t; ++qwertz) {
            cin >> insignificant_word;
            insignificant_words.insert(insignificant_word);
        }

        string line;
        // read all the words
        getline(cin, line); // read \n

        while (true) {
            getline(cin, line);

            istringstream iss(line);

            getline(iss, abbreviation, ' ');
            abbr = abbreviation;
            transform(abbreviation.begin(), abbreviation.end(), abbr.begin(), ::tolower);
            abbr_len = abbr.size();

            vector<string> words;
            string word;
            getline(iss, word, ' ');

            if (abbreviation == "LAST" && word == "CASE") break;

            do {
                if (!word.empty() && insignificant_words.find(word) == insignificant_words.end()) {
                    words.push_back(word);
                }
            } while (getline(iss, word, ' '));

            phrase = "";
            for (vector<string>::iterator it = words.begin(); it != words.end(); ++it) {
                phrase += ' ' + *it;
            }
            phrase_len = phrase.size();

            memset(dp, -1, sizeof dp);
            int sol = rek(1);

            if (sol) cout << abbreviation << " can be formed in " << sol << " ways" << endl;
            else cout << abbreviation << " is not a valid abbreviation" << endl;
        }
    }

    return 0;
}<|endoftext|>


<commit_before>#ifndef GCL_FILESYSTEM_HPP__
# define GCL_FILESYSTEM_HPP__

# include <stdexcept>
# include <functional>
# include <vector>

#ifdef _WIN32
# include <Windows.h>
# include <strsafe.h>
#endif

namespace gcl
{
	// todo : unix/linux impl
	namespace filesystem
	{
		namespace exception
		{
			struct bad_path : std::runtime_error
			{
				bad_path(const std::string & path)
					: std::runtime_error("gcl::fs : Bad path : [" + path + "]")
				{}
			};
			struct walk_error : std::runtime_error
			{
				walk_error(const std::string & path)
					: std::runtime_error("gcl::fs : walk error : [" + path + "]")
				{}
			};
		}

		struct path
		{
			path(const std::string & str)
				: value{ str }
			{}
			path(const path & other)
				: value(other)
				, is_valid(other.is_valid)
			{}
			path(path && other)
				: value(std::move(other.value))
				, is_valid(std::move(other.is_valid))
			{}

			inline operator const std::string &() const
			{
				return value;
			}
			inline operator const char *() const
			{
				return value.c_str();
			}
			inline bool operator!() const
			{
				if (is_valid)
					return true;

				std::size_t length;
				StringCchLength(value.c_str(), MAX_PATH, &length);
				return (const_cast<path*>(this)->is_valid = (length > (MAX_PATH - 3)));
			}

			inline path operator+(const std::string & str) const
			{
				return path{ value + str };
			}
			inline path & operator=(const std::string & str)
			{
				value = str;
				is_valid = false;

				return *this;
			}

		protected:
			std::string value;
			bool is_valid = false;
		};
		// todo : extension : *.png
		struct directory
		{
			enum walk_logic
			{
				non_recursive,
				recursive
			};

			directory(const std::string & path_v)
				: path(path_v)
			{}

			template <walk_logic is_rec = non_recursive>
			std::vector<std::string> directories()
			{
				std::vector<std::string> dirlist;

				walk_routine_t fun = [&dirlist](const std::string & filename, bool is_dir)
				{
					if (is_dir)
						dirlist.push_back(filename);
				};
				walk<is_rec>(path, fun);

				return dirlist;
			}
			template <walk_logic is_rec = non_recursive>
			std::vector<std::string> files()
			{
				std::vector<std::string> filelist;

				auto fun = [&filelist](const std::string & filename, bool is_dir)
				{
					if (!is_dir)
						filelist.push_back(filename);
				};
				walk<is_rec>(path, fun);

				return filelist;
			}
			template <walk_logic is_rec = non_recursive>
			std::vector<std::string> content()
			{
				std::vector<std::string> contentlist;

				auto fun = [&contentlist](const std::string & filename, bool is_dir)
				{
					contentlist.push_back(filename);
				};
				walk<is_rec>(path, fun);

				return contentlist;
			}

			using walk_routine_t = std::function<void(const std::string & /*filename*/, bool /*is_dir*/)>;
			template <walk_logic is_rec = non_recursive>
			void walk(const filesystem::path & path_value, walk_routine_t fun)
			{
				walk_impl<is_rec>(path_value, fun);
			}

		protected:
			filesystem::path path;

#ifdef WIN32
			template <walk_logic is_rec>
			void walk_impl(const filesystem::path & path_value, walk_routine_t fun)
			{
				if (!path_value)
					throw exception::bad_path{ path_value };

				HANDLE handle{ INVALID_HANDLE_VALUE };

				TCHAR cache[MAX_PATH];
				StringCchCopy(cache, MAX_PATH, path_value);
				StringCchCat(cache, MAX_PATH, TEXT("\\*"));

				WIN32_FIND_DATA find_data;
				bool next_success{ true };

				for (handle = FindFirstFile(cache, &find_data);
					handle != INVALID_HANDLE_VALUE && next_success;
					next_success = (FindNextFile(handle, &find_data) != 0))
				{
					if (strcmp(find_data.cFileName, ".") != 0 &&
						strcmp(find_data.cFileName, "..") != 0)
					{
						const bool is_dir = find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
						auto file_path = path_value + "/" + find_data.cFileName;
						fun(file_path, is_dir);
						if (is_dir && is_rec)
							walk_impl<is_rec>(file_path, fun);
					}
				}
				if (GetLastError() != ERROR_NO_MORE_FILES)
					throw exception::walk_error(path_value);

			}
#else
			static_assert(false, "gcl::filesystem::directory::walk : not implemented");
			template <walk_logic is_rec>
			void walk_impl(const filesystem::path & path_value, walk_routine_t fun)
			{}
#endif
		};
	}
}

#endif // GCL_FILESYSTEM_HPP__<commit_msg>gcl::filesystem::directory : add todo for extension to use regex<commit_after>#ifndef GCL_FILESYSTEM_HPP__
# define GCL_FILESYSTEM_HPP__

# include <stdexcept>
# include <functional>
# include <vector>

#ifdef _WIN32
# include <Windows.h>
# include <strsafe.h>
#endif

namespace gcl
{
	// todo : unix/linux impl
	namespace filesystem
	{
		namespace exception
		{
			struct bad_path : std::runtime_error
			{
				bad_path(const std::string & path)
					: std::runtime_error("gcl::fs : Bad path : [" + path + "]")
				{}
			};
			struct walk_error : std::runtime_error
			{
				walk_error(const std::string & path)
					: std::runtime_error("gcl::fs : walk error : [" + path + "]")
				{}
			};
		}

		struct path
		{
			path(const std::string & str)
				: value{ str }
			{}
			path(const path & other)
				: value(other)
				, is_valid(other.is_valid)
			{}
			path(path && other)
				: value(std::move(other.value))
				, is_valid(std::move(other.is_valid))
			{}

			inline operator const std::string &() const
			{
				return value;
			}
			inline operator const char *() const
			{
				return value.c_str();
			}
			inline bool operator!() const
			{
				if (is_valid)
					return true;

				std::size_t length;
				StringCchLength(value.c_str(), MAX_PATH, &length);
				return (const_cast<path*>(this)->is_valid = (length > (MAX_PATH - 3)));
			}

			inline path operator+(const std::string & str) const
			{
				return path{ value + str };
			}
			inline path & operator=(const std::string & str)
			{
				value = str;
				is_valid = false;

				return *this;
			}

		protected:
			std::string value;
			bool is_valid = false;
		};
		// todo : extension : *.png -> use regex [?]
		struct directory
		{
			enum walk_logic
			{
				non_recursive,
				recursive
			};

			directory(const std::string & path_v)
				: path(path_v)
			{}

			template <walk_logic is_rec = non_recursive>
			std::vector<std::string> directories()
			{
				std::vector<std::string> dirlist;

				walk_routine_t fun = [&dirlist](const std::string & filename, bool is_dir)
				{
					if (is_dir)
						dirlist.push_back(filename);
				};
				walk<is_rec>(path, fun);

				return dirlist;
			}
			template <walk_logic is_rec = non_recursive>
			std::vector<std::string> files()
			{
				std::vector<std::string> filelist;

				auto fun = [&filelist](const std::string & filename, bool is_dir)
				{
					if (!is_dir)
						filelist.push_back(filename);
				};
				walk<is_rec>(path, fun);

				return filelist;
			}
			template <walk_logic is_rec = non_recursive>
			std::vector<std::string> content()
			{
				std::vector<std::string> contentlist;

				auto fun = [&contentlist](const std::string & filename, bool is_dir)
				{
					contentlist.push_back(filename);
				};
				walk<is_rec>(path, fun);

				return contentlist;
			}

			using walk_routine_t = std::function<void(const std::string & /*filename*/, bool /*is_dir*/)>;
			template <walk_logic is_rec = non_recursive>
			void walk(const filesystem::path & path_value, walk_routine_t fun)
			{
				walk_impl<is_rec>(path_value, fun);
			}

		protected:
			filesystem::path path;

#ifdef WIN32
			template <walk_logic is_rec>
			void walk_impl(const filesystem::path & path_value, walk_routine_t fun)
			{
				if (!path_value)
					throw exception::bad_path{ path_value };

				HANDLE handle{ INVALID_HANDLE_VALUE };

				TCHAR cache[MAX_PATH];
				StringCchCopy(cache, MAX_PATH, path_value);
				StringCchCat(cache, MAX_PATH, TEXT("\\*"));

				WIN32_FIND_DATA find_data;
				bool next_success{ true };

				for (handle = FindFirstFile(cache, &find_data);
					handle != INVALID_HANDLE_VALUE && next_success;
					next_success = (FindNextFile(handle, &find_data) != 0))
				{
					if (strcmp(find_data.cFileName, ".") != 0 &&
						strcmp(find_data.cFileName, "..") != 0)
					{
						const bool is_dir = find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
						auto file_path = path_value + "/" + find_data.cFileName;
						fun(file_path, is_dir);
						if (is_dir && is_rec)
							walk_impl<is_rec>(file_path, fun);
					}
				}
				if (GetLastError() != ERROR_NO_MORE_FILES)
					throw exception::walk_error(path_value);

			}
#else
			static_assert(false, "gcl::filesystem::directory::walk : not implemented");
			template <walk_logic is_rec>
			void walk_impl(const filesystem::path & path_value, walk_routine_t fun)
			{}
#endif
		};
	}
}

#endif // GCL_FILESYSTEM_HPP__<|endoftext|>