<commit_before>#include "path_renderer.hpp"
#include "resource.hpp"
#include "pen.hpp"
#include "resource_cache.hpp"

#include "opengl/base_texture.hpp"

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

namespace graphics
{
  PathRenderer::Params::Params()
    : m_drawPathes(true),
      m_fastSolidPath(true)
  {}

  PathRenderer::PathRenderer(Params const & params)
    : base_t(params),
      m_drawPathes(params.m_drawPathes),
      m_fastSolidPath(params.m_fastSolidPath)
  {}

  void PathRenderer::drawPath(m2::PointD const * pts, size_t ptsCount, double offset, uint32_t resID, double depth)
  {
    ++m_pathCount;
    m_pointsCount += ptsCount;

    if (!m_drawPathes)
      return;

    ASSERT_GREATER_OR_EQUAL(ptsCount, 2, ());
    ASSERT_NOT_EQUAL(resID, uint32_t(-1), ());

    Resource const * res = base_t::fromID(resID);

    if (res == 0)
    {
      LOG(LINFO, ("drawPath: resID=", resID, "wasn't found on current skin"));
      return;
    }

    ASSERT(res->m_cat == Resource::EPen, ());

    Pen const * pen = static_cast<Pen const *>(res);

    if (!pen->m_info.m_symbol.empty())
      drawSymbolPath(pts, ptsCount, offset, pen, depth);
    else
      if (m_fastSolidPath && pen->m_isSolid)
        drawSolidPath(pts, ptsCount, offset, pen, depth);
      else
        drawStipplePath(pts, ptsCount, offset, pen, depth);
  }

  void PathRenderer::drawSymbolPath(m2::PointD const * pts, size_t ptsCount, double offset, Pen const * pen, double depth)
  {
    LOG(LINFO, ("drawSymbolPath is unimplemented. symbolName=", pen->m_info.m_symbol));
  }

  void PathRenderer::drawStipplePath(m2::PointD const * points, size_t pointsCount, double offset, Pen const * pen, double depth)
  {
    float rawTileStartLen = 0;

    float rawTileLen = (float)pen->rawTileLen();

    if ((offset < 0) && (!pen->m_isWrapped))
      offset = offset - rawTileLen * ceil(offset / rawTileLen);

    bool skipToOffset = true;

    for (size_t i = 0; i < pointsCount - 1; ++i)
    {
      m2::PointD dir = points[i + 1] - points[i];
      dir *= 1.0 / dir.Length(m2::PointD(0, 0));
      m2::PointD norm(-dir.y, dir.x);

      /// The length of the current segment.
      float segLen = points[i + 1].Length(points[i]);
      /// The remaining length of the segment
      float segLenRemain = segLen;

      if (skipToOffset)
      {
        offset -= segLen;
        if (offset >= 0)
          continue;
        else
        {
          skipToOffset = false;
          segLenRemain = -offset;
        }
      }

      /// Geometry width. It's 1px wider than the pattern width.
      int geomWidth = static_cast<int>(pen->m_info.m_w) + 4 - 2 * aaShift();
      float geomHalfWidth =  geomWidth / 2.0;

      /// Starting point of the tiles on this segment
      m2::PointF rawTileStartPt = points[i] + dir * (segLen - segLenRemain);

      /// Tiling procedes as following :
      /// The leftmost tile goes antialiased at left and non-antialiased at right.
      /// The inner tiles goes non-antialiased at both sides.
      /// The rightmost tile goes non-antialised at left and antialiased at right side.

      /// Length of the actual pattern data being tiling(without antialiasing zones).
      rawTileLen = 0;

      GeometryPipeline & p = pipeline(pen->m_pipelineID);

      shared_ptr<gl::BaseTexture> texture = p.texture();

      if (!texture)
      {
        LOG(LDEBUG, ("returning as no texture is reserved"));
        return;
      }

      float texMaxY = pen->m_texRect.maxY() - aaShift();
      float texMinY = pen->m_texRect.minY() + aaShift();

      m2::PointF const fNorm = norm * geomHalfWidth;  // enough to calc it once

      while (segLenRemain > 0)
      {
        rawTileLen = pen->m_isWrapped
            ? segLen
            : std::min(((float)pen->rawTileLen() - rawTileStartLen), segLenRemain);

        float texMinX = pen->m_isWrapped ? 0 : pen->m_texRect.minX() + 2 + rawTileStartLen;
        float texMaxX = texMinX + rawTileLen;

        rawTileStartLen += rawTileLen;
        if (rawTileStartLen >= pen->rawTileLen())
          rawTileStartLen -= pen->rawTileLen();
        ASSERT(rawTileStartLen < pen->rawTileLen(), ());

        m2::PointF rawTileEndPt(rawTileStartPt.x + dir.x * rawTileLen, rawTileStartPt.y + dir.y * rawTileLen);

        m2::PointF coords[4] =
        {
          rawTileStartPt + fNorm,
          rawTileStartPt - fNorm,
          rawTileEndPt - fNorm,
          rawTileEndPt + fNorm
        };

        m2::PointF texCoords[4] =
        {
          texture->mapPixel(m2::PointF(texMinX, texMinY)),
          texture->mapPixel(m2::PointF(texMinX, texMaxY)),
          texture->mapPixel(m2::PointF(texMaxX, texMaxY)),
          texture->mapPixel(m2::PointF(texMaxX, texMinY))
        };

        m2::PointF normals[4] =
        {
          m2::PointF(0, 0),
          m2::PointF(0, 0),
          m2::PointF(0, 0),
          m2::PointF(0, 0)
        };

        addTexturedFan(coords,
                       normals,
                       texCoords,
                       4,
                       depth,
                       pen->m_pipelineID);

        segLenRemain -= rawTileLen;

        rawTileStartPt = rawTileEndPt;
      }

      bool isColorJoin = pen->m_isSolid ? true : pen->m_info.atDashOffset(rawTileLen);

      /// Adding geometry for a line join between previous and current segment.
      if ((i != pointsCount - 2) && (isColorJoin))
      {
        m2::PointD nextDir = points[i + 2] - points[i + 1];
        nextDir *= 1.0 / nextDir.Length(m2::PointD(0, 0));
        m2::PointD nextNorm(-nextDir.y, nextDir.x);

        /// Computing the sin of angle between directions.
        double alphaSin = dir.x * nextDir.y - dir.y * nextDir.x;
        double alphaCos = dir.x * nextDir.x + dir.y * nextDir.y;
        double alpha = atan2(alphaSin, alphaCos);
        int angleSegCount = int(ceil(fabs(alpha) / (math::pi / 6)));
        double angleStep = alpha / angleSegCount;

        m2::PointD startVec;

        if (alpha > 0)
        {
          /// The outer site is on the prevNorm direction.
          startVec = -norm;
        }
        else
        {
          /// The outer site is on the -prevNorm direction
          startVec = norm;
        }

        GeometryPipeline & p = pipeline(pen->m_pipelineID);

        shared_ptr<gl::BaseTexture> texture = p.texture();

        if (!texture)
        {
          LOG(LDEBUG, ("returning as no texture is reserved"));
          return;
        }

        m2::PointF joinSegTex[3] =
        {
          texture->mapPixel(pen->m_centerColorPixel),
          texture->mapPixel(pen->m_borderColorPixel),
          texture->mapPixel(pen->m_borderColorPixel)
        };

        m2::PointD prevStartVec = startVec;
        for (int j = 0; j < angleSegCount; ++j)
        {
          /// Rotate start vector to find another point on a join.
          startVec.Rotate(angleStep);

          /// Computing three points of a join segment.
          m2::PointF joinSeg[3] =
          {
            m2::PointF(points[i + 1]),
            m2::PointF(points[i + 1] + startVec * geomHalfWidth),
            m2::PointF(points[i + 1] + prevStartVec * geomHalfWidth)
          };

          m2::PointF joinSegNormals[3] =
          {
            m2::PointF(0, 0),
            m2::PointF(0, 0),
            m2::PointF(0, 0)
          };

          addTexturedFan(joinSeg,
                         joinSegNormals,
                         joinSegTex,
                         3,
                         depth,
                         pen->m_pipelineID);

          prevStartVec = startVec;
        }
      }
    }
  }

  void PathRenderer::drawSolidPath(m2::PointD const * points, size_t pointsCount, double offset, Pen const * pen, double depth)
  {
    ASSERT(pen->m_isSolid, ());

    bool const hasRoundCap = (pen->m_info.m_cap == pen->m_info.ERoundCap);
    bool const hasSquareCap = (pen->m_info.m_cap == pen->m_info.ESquareCap);
    bool const hasRoundJoin = (pen->m_info.m_join == pen->m_info.ERoundJoin);
    bool const hasBevelJoin = (pen->m_info.m_join == pen->m_info.EBevelJoin);

    float geomHalfWidth = (pen->m_info.m_w + 4 - aaShift() * 2) / 2.0;

    m2::PointD dir = points[1] - points[0];
    double len = dir.Length(m2::PointD(0, 0));
    dir *= 1.0 / len;
    m2::PointD const norm(-dir.y, dir.x);
    m2::PointD fNorm = norm * geomHalfWidth;
    m2::PointD fDir(fNorm.y, -fNorm.x);

    m2::PointD fNormNextSeg;
    m2::PointD fDirNextSeg;

    for (size_t i = 0; i < pointsCount - 1; ++i)
    {
      bool const leftIsCap  = i == 0;
      bool const rightIsCap = i == (pointsCount - 2);

      if (!leftIsCap)
      {
        fNorm = fNormNextSeg;
        fDir = fDirNextSeg;
      }

      m2::PointD const & nextPt = points[i + 1];

      if (!rightIsCap)
      {
        m2::PointD dirNextSeg = points[i + 2] - points[i + 1];
        double lenNextSeg = dirNextSeg.Length(m2::PointD(0, 0));
        dirNextSeg *= 1.0 / lenNextSeg;
        m2::PointD normNextSeg(-dirNextSeg.y, dirNextSeg.x);
        fNormNextSeg = normNextSeg * geomHalfWidth;
        fDirNextSeg = m2::PointD(fNormNextSeg.y, -fNormNextSeg.x);
      }

      float texMinX = pen->m_texRect.minX() + 1;
      float texMaxX = pen->m_texRect.maxX() - 1;

      float texMinY = pen->m_texRect.maxY() - aaShift();
      float texMaxY = pen->m_texRect.minY() + aaShift();

      float texCenterX = (texMinX + texMaxX) / 2;

      int numPoints = 4;

      if (leftIsCap && (hasRoundCap || hasSquareCap))
        numPoints += 2;
      if ((rightIsCap && (hasRoundCap || hasSquareCap))
       || (!rightIsCap && (hasRoundJoin || hasBevelJoin)))
        numPoints += 2;

      int cur = 0;

      m2::PointF coords[numPoints];

      if (leftIsCap && (hasRoundCap || hasSquareCap))
      {
        coords[cur++] = points[i] - fDir + fNorm;
        coords[cur++] = points[i] - fDir - fNorm;
      }

      coords[cur++] = points[i] + fNorm;
      coords[cur++] = points[i] - fNorm;
      coords[cur++] = nextPt + fNorm;
      coords[cur++] = nextPt - fNorm;

      if ((rightIsCap && (hasRoundCap || hasSquareCap))
       || (!rightIsCap && hasRoundJoin))
      {
        coords[cur++] = nextPt + fDir + fNorm;
        coords[cur++] = nextPt + fDir - fNorm;
      }
      else if (!rightIsCap && hasBevelJoin)
      {
        coords[cur++] = points[i + 1] + fNormNextSeg;
        coords[cur++] = points[i + 1] - fNormNextSeg;
      }

      GeometryPipeline & p = pipeline(pen->m_pipelineID);

      shared_ptr<gl::BaseTexture> texture = p.texture();

      if (!texture)
      {
        LOG(LDEBUG, ("returning as no texture is reserved"));
        return;
      }

      m2::PointF texCoords[numPoints];
      cur = 0;

      if (leftIsCap && hasRoundCap)
      {
        texCoords[cur++] = texture->mapPixel(m2::PointF(texMinX, texMinY));
        texCoords[cur++] = texture->mapPixel(m2::PointF(texMinX, texMaxY));
      }
      else if (leftIsCap && hasSquareCap)
      {
        texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMinY));
        texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMaxY));
      }

      texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMinY));
      texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMaxY));
      texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMinY));
      texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMaxY));

      if ((rightIsCap && hasRoundCap)
       || (!rightIsCap && hasRoundJoin))
      {
        texCoords[cur++] = texture->mapPixel(m2::PointF(texMaxX, texMinY));
        texCoords[cur++] = texture->mapPixel(m2::PointF(texMaxX, texMaxY));
      }
      else if ((rightIsCap && hasSquareCap)
            || (!rightIsCap && hasBevelJoin))
      {
        texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMinY));
        texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMaxY));
      }

      m2::PointF normal(0, 0);

      addTexturedStripStrided(coords, sizeof(m2::PointF),
                              &normal, 0,
                              texCoords, sizeof(m2::PointF),
                              numPoints,
                              depth,
                              pen->m_pipelineID);
    }
  }

  void PathRenderer::beginFrame()
  {
    base_t::beginFrame();
    m_pathCount = 0;
    m_pointsCount = 0;
  }

  void PathRenderer::endFrame()
  {
    if (isDebugging())
    {
      LOG(LINFO, ("drawing ", m_pathCount, " pathes, ", m_pointsCount, " points total"));
    }
    base_t::endFrame();
  }
}

<commit_msg>clang compile fix<commit_after>#include "path_renderer.hpp"
#include "resource.hpp"
#include "pen.hpp"
#include "resource_cache.hpp"

#include "opengl/base_texture.hpp"

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

namespace graphics
{
  PathRenderer::Params::Params()
    : m_drawPathes(true),
      m_fastSolidPath(true)
  {}

  PathRenderer::PathRenderer(Params const & params)
    : base_t(params),
      m_drawPathes(params.m_drawPathes),
      m_fastSolidPath(params.m_fastSolidPath)
  {}

  void PathRenderer::drawPath(m2::PointD const * pts, size_t ptsCount, double offset, uint32_t resID, double depth)
  {
    ++m_pathCount;
    m_pointsCount += ptsCount;

    if (!m_drawPathes)
      return;

    ASSERT_GREATER_OR_EQUAL(ptsCount, 2, ());
    ASSERT_NOT_EQUAL(resID, uint32_t(-1), ());

    Resource const * res = base_t::fromID(resID);

    if (res == 0)
    {
      LOG(LINFO, ("drawPath: resID=", resID, "wasn't found on current skin"));
      return;
    }

    ASSERT(res->m_cat == Resource::EPen, ());

    Pen const * pen = static_cast<Pen const *>(res);

    if (!pen->m_info.m_symbol.empty())
      drawSymbolPath(pts, ptsCount, offset, pen, depth);
    else
      if (m_fastSolidPath && pen->m_isSolid)
        drawSolidPath(pts, ptsCount, offset, pen, depth);
      else
        drawStipplePath(pts, ptsCount, offset, pen, depth);
  }

  void PathRenderer::drawSymbolPath(m2::PointD const * pts, size_t ptsCount, double offset, Pen const * pen, double depth)
  {
    LOG(LINFO, ("drawSymbolPath is unimplemented. symbolName=", pen->m_info.m_symbol));
  }

  void PathRenderer::drawStipplePath(m2::PointD const * points, size_t pointsCount, double offset, Pen const * pen, double depth)
  {
    float rawTileStartLen = 0;

    float rawTileLen = (float)pen->rawTileLen();

    if ((offset < 0) && (!pen->m_isWrapped))
      offset = offset - rawTileLen * ceil(offset / rawTileLen);

    bool skipToOffset = true;

    for (size_t i = 0; i < pointsCount - 1; ++i)
    {
      m2::PointD dir = points[i + 1] - points[i];
      dir *= 1.0 / dir.Length(m2::PointD(0, 0));
      m2::PointD norm(-dir.y, dir.x);

      /// The length of the current segment.
      float segLen = points[i + 1].Length(points[i]);
      /// The remaining length of the segment
      float segLenRemain = segLen;

      if (skipToOffset)
      {
        offset -= segLen;
        if (offset >= 0)
          continue;
        else
        {
          skipToOffset = false;
          segLenRemain = -offset;
        }
      }

      /// Geometry width. It's 1px wider than the pattern width.
      int geomWidth = static_cast<int>(pen->m_info.m_w) + 4 - 2 * aaShift();
      float geomHalfWidth =  geomWidth / 2.0;

      /// Starting point of the tiles on this segment
      m2::PointF rawTileStartPt = points[i] + dir * (segLen - segLenRemain);

      /// Tiling procedes as following :
      /// The leftmost tile goes antialiased at left and non-antialiased at right.
      /// The inner tiles goes non-antialiased at both sides.
      /// The rightmost tile goes non-antialised at left and antialiased at right side.

      /// Length of the actual pattern data being tiling(without antialiasing zones).
      rawTileLen = 0;

      GeometryPipeline & p = pipeline(pen->m_pipelineID);

      shared_ptr<gl::BaseTexture> texture = p.texture();

      if (!texture)
      {
        LOG(LDEBUG, ("returning as no texture is reserved"));
        return;
      }

      float texMaxY = pen->m_texRect.maxY() - aaShift();
      float texMinY = pen->m_texRect.minY() + aaShift();

      m2::PointF const fNorm = norm * geomHalfWidth;  // enough to calc it once

      while (segLenRemain > 0)
      {
        rawTileLen = pen->m_isWrapped
            ? segLen
            : std::min(((float)pen->rawTileLen() - rawTileStartLen), segLenRemain);

        float texMinX = pen->m_isWrapped ? 0 : pen->m_texRect.minX() + 2 + rawTileStartLen;
        float texMaxX = texMinX + rawTileLen;

        rawTileStartLen += rawTileLen;
        if (rawTileStartLen >= pen->rawTileLen())
          rawTileStartLen -= pen->rawTileLen();
        ASSERT(rawTileStartLen < pen->rawTileLen(), ());

        m2::PointF rawTileEndPt(rawTileStartPt.x + dir.x * rawTileLen, rawTileStartPt.y + dir.y * rawTileLen);

        m2::PointF coords[4] =
        {
          rawTileStartPt + fNorm,
          rawTileStartPt - fNorm,
          rawTileEndPt - fNorm,
          rawTileEndPt + fNorm
        };

        m2::PointF texCoords[4] =
        {
          texture->mapPixel(m2::PointF(texMinX, texMinY)),
          texture->mapPixel(m2::PointF(texMinX, texMaxY)),
          texture->mapPixel(m2::PointF(texMaxX, texMaxY)),
          texture->mapPixel(m2::PointF(texMaxX, texMinY))
        };

        m2::PointF normals[4] =
        {
          m2::PointF(0, 0),
          m2::PointF(0, 0),
          m2::PointF(0, 0),
          m2::PointF(0, 0)
        };

        addTexturedFan(coords,
                       normals,
                       texCoords,
                       4,
                       depth,
                       pen->m_pipelineID);

        segLenRemain -= rawTileLen;

        rawTileStartPt = rawTileEndPt;
      }

      bool isColorJoin = pen->m_isSolid ? true : pen->m_info.atDashOffset(rawTileLen);

      /// Adding geometry for a line join between previous and current segment.
      if ((i != pointsCount - 2) && (isColorJoin))
      {
        m2::PointD nextDir = points[i + 2] - points[i + 1];
        nextDir *= 1.0 / nextDir.Length(m2::PointD(0, 0));
        m2::PointD nextNorm(-nextDir.y, nextDir.x);

        /// Computing the sin of angle between directions.
        double alphaSin = dir.x * nextDir.y - dir.y * nextDir.x;
        double alphaCos = dir.x * nextDir.x + dir.y * nextDir.y;
        double alpha = atan2(alphaSin, alphaCos);
        int angleSegCount = int(ceil(fabs(alpha) / (math::pi / 6)));
        double angleStep = alpha / angleSegCount;

        m2::PointD startVec;

        if (alpha > 0)
        {
          /// The outer site is on the prevNorm direction.
          startVec = -norm;
        }
        else
        {
          /// The outer site is on the -prevNorm direction
          startVec = norm;
        }

        GeometryPipeline & p = pipeline(pen->m_pipelineID);

        shared_ptr<gl::BaseTexture> texture = p.texture();

        if (!texture)
        {
          LOG(LDEBUG, ("returning as no texture is reserved"));
          return;
        }

        m2::PointF joinSegTex[3] =
        {
          texture->mapPixel(pen->m_centerColorPixel),
          texture->mapPixel(pen->m_borderColorPixel),
          texture->mapPixel(pen->m_borderColorPixel)
        };

        m2::PointD prevStartVec = startVec;
        for (int j = 0; j < angleSegCount; ++j)
        {
          /// Rotate start vector to find another point on a join.
          startVec.Rotate(angleStep);

          /// Computing three points of a join segment.
          m2::PointF joinSeg[3] =
          {
            m2::PointF(points[i + 1]),
            m2::PointF(points[i + 1] + startVec * geomHalfWidth),
            m2::PointF(points[i + 1] + prevStartVec * geomHalfWidth)
          };

          m2::PointF joinSegNormals[3] =
          {
            m2::PointF(0, 0),
            m2::PointF(0, 0),
            m2::PointF(0, 0)
          };

          addTexturedFan(joinSeg,
                         joinSegNormals,
                         joinSegTex,
                         3,
                         depth,
                         pen->m_pipelineID);

          prevStartVec = startVec;
        }
      }
    }
  }

  void PathRenderer::drawSolidPath(m2::PointD const * points, size_t pointsCount, double offset, Pen const * pen, double depth)
  {
    ASSERT(pen->m_isSolid, ());

    bool const hasRoundCap = (pen->m_info.m_cap == pen->m_info.ERoundCap);
    bool const hasSquareCap = (pen->m_info.m_cap == pen->m_info.ESquareCap);
    bool const hasRoundJoin = (pen->m_info.m_join == pen->m_info.ERoundJoin);
    bool const hasBevelJoin = (pen->m_info.m_join == pen->m_info.EBevelJoin);

    float geomHalfWidth = (pen->m_info.m_w + 4 - aaShift() * 2) / 2.0;

    m2::PointD dir = points[1] - points[0];
    double len = dir.Length(m2::PointD(0, 0));
    dir *= 1.0 / len;
    m2::PointD const norm(-dir.y, dir.x);
    m2::PointD fNorm = norm * geomHalfWidth;
    m2::PointD fDir(fNorm.y, -fNorm.x);

    m2::PointD fNormNextSeg;
    m2::PointD fDirNextSeg;

    for (size_t i = 0; i < pointsCount - 1; ++i)
    {
      bool const leftIsCap  = i == 0;
      bool const rightIsCap = i == (pointsCount - 2);

      if (!leftIsCap)
      {
        fNorm = fNormNextSeg;
        fDir = fDirNextSeg;
      }

      m2::PointD const & nextPt = points[i + 1];

      if (!rightIsCap)
      {
        m2::PointD dirNextSeg = points[i + 2] - points[i + 1];
        double lenNextSeg = dirNextSeg.Length(m2::PointD(0, 0));
        dirNextSeg *= 1.0 / lenNextSeg;
        m2::PointD normNextSeg(-dirNextSeg.y, dirNextSeg.x);
        fNormNextSeg = normNextSeg * geomHalfWidth;
        fDirNextSeg = m2::PointD(fNormNextSeg.y, -fNormNextSeg.x);
      }

      float texMinX = pen->m_texRect.minX() + 1;
      float texMaxX = pen->m_texRect.maxX() - 1;

      float texMinY = pen->m_texRect.maxY() - aaShift();
      float texMaxY = pen->m_texRect.minY() + aaShift();

      float texCenterX = (texMinX + texMaxX) / 2;

      int numPoints = 4;

      if (leftIsCap && (hasRoundCap || hasSquareCap))
        numPoints += 2;
      if ((rightIsCap && (hasRoundCap || hasSquareCap))
       || (!rightIsCap && (hasRoundJoin || hasBevelJoin)))
        numPoints += 2;

      int cur = 0;

      ASSERT(numPoints <= 8, ("numPoints is more than 8, won't fit in array"));
      m2::PointF coords[8];

      if (leftIsCap && (hasRoundCap || hasSquareCap))
      {
        coords[cur++] = points[i] - fDir + fNorm;
        coords[cur++] = points[i] - fDir - fNorm;
      }

      coords[cur++] = points[i] + fNorm;
      coords[cur++] = points[i] - fNorm;
      coords[cur++] = nextPt + fNorm;
      coords[cur++] = nextPt - fNorm;

      if ((rightIsCap && (hasRoundCap || hasSquareCap))
       || (!rightIsCap && hasRoundJoin))
      {
        coords[cur++] = nextPt + fDir + fNorm;
        coords[cur++] = nextPt + fDir - fNorm;
      }
      else if (!rightIsCap && hasBevelJoin)
      {
        coords[cur++] = points[i + 1] + fNormNextSeg;
        coords[cur++] = points[i + 1] - fNormNextSeg;
      }

      GeometryPipeline & p = pipeline(pen->m_pipelineID);

      shared_ptr<gl::BaseTexture> texture = p.texture();

      if (!texture)
      {
        LOG(LDEBUG, ("returning as no texture is reserved"));
        return;
      }

      m2::PointF texCoords[8];
      cur = 0;

      if (leftIsCap && hasRoundCap)
      {
        texCoords[cur++] = texture->mapPixel(m2::PointF(texMinX, texMinY));
        texCoords[cur++] = texture->mapPixel(m2::PointF(texMinX, texMaxY));
      }
      else if (leftIsCap && hasSquareCap)
      {
        texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMinY));
        texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMaxY));
      }

      texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMinY));
      texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMaxY));
      texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMinY));
      texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMaxY));

      if ((rightIsCap && hasRoundCap)
       || (!rightIsCap && hasRoundJoin))
      {
        texCoords[cur++] = texture->mapPixel(m2::PointF(texMaxX, texMinY));
        texCoords[cur++] = texture->mapPixel(m2::PointF(texMaxX, texMaxY));
      }
      else if ((rightIsCap && hasSquareCap)
            || (!rightIsCap && hasBevelJoin))
      {
        texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMinY));
        texCoords[cur++] = texture->mapPixel(m2::PointF(texCenterX, texMaxY));
      }

      m2::PointF normal(0, 0);

      addTexturedStripStrided(coords, sizeof(m2::PointF),
                              &normal, 0,
                              texCoords, sizeof(m2::PointF),
                              numPoints,
                              depth,
                              pen->m_pipelineID);
    }
  }

  void PathRenderer::beginFrame()
  {
    base_t::beginFrame();
    m_pathCount = 0;
    m_pointsCount = 0;
  }

  void PathRenderer::endFrame()
  {
    if (isDebugging())
    {
      LOG(LINFO, ("drawing ", m_pathCount, " pathes, ", m_pointsCount, " points total"));
    }
    base_t::endFrame();
  }
}

<|endoftext|>


<commit_before>#include "savesaccess.h"

#include <QtWidgets/QApplication>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QWidget>
#include <QDebug>

SavesAccess::SavesAccess(QObject *parent) :
    QObject(parent),
    savedGameModel(Q_NULLPTR),
    resourceModel(Q_NULLPTR)
{
}

// Sets the path and loads the game.
void SavesAccess::loadSavedGame(QString gameName)
{
    // Set the game name.
    selectedSaveName = gameName;

    // Pull the resources into the list.
    loadResourceFile();
    loadUnitFile();
}

void SavesAccess::saveSavedGame()
{
    saveResourceFile();
    //saveUnitsToFile();
    //saveTimeToFile();
    //saveGameOverviewToFile();
}

void SavesAccess::openFileDialog()
{

    // TODO: Set the parent of this dialog so it returns properly.
    // Not sure if this is the cause of the weird Windows behavior
    // or not. Something to try.
    QFileDialog fileDialog(0,"Timber and Stone saves.sav file");
    fileDialog.setDirectory(rootSavesDirectory);
    fileDialog.setNameFilter("Saves File (saves.sav)");

    // Open the file dialog so the user can select the saves.sav file.
    if (fileDialog.exec())
    {
        rootSavesDirectory.setPath(fileDialog.selectedFiles().first());
        rootSavesDirectory.cdUp(); // This trims off the saves.sav file.
    }
}

// NOTE: Qml access this for types that are explicitly typed in.
void SavesAccess::setFilePath(QString path)
{
    // Save the path to the file.
    rootSavesDirectory.setPath(path);
    rootSavesDirectory.cdUp();
}

QString SavesAccess::getSavesPath()
{
    return (rootSavesDirectory.absolutePath() + "/" + "saves.sav");
}

bool SavesAccess::pathIsValid()
{
    // Return True if both the directory path is valid
    // and the saves.sav file exists.
    QFile savedGameFile(getSavesPath());
    QFileInfo fileInfo(savedGameFile);
    if (savedGameFile.exists() && (fileInfo.fileName() == "saves.sav"))
    {
        return true;
    }
    else
    {
        return false;
    }
}

void SavesAccess::loadGamesList()
{
    // Save the file name.
    QFile savedGameFile(rootSavesDirectory.absolutePath()
                        + "/" + "saves.sav");

    if (savedGameModel == Q_NULLPTR)
    {
        qDebug() << "SavedAccess model hasn't been set up yet.";
        return;
    }

    // Open file and make sure it went okay.
    if (!savedGameFile.exists() || !savedGameFile.open(QFile::ReadOnly | QFile::Text))
    {
        // TODO: Make this error apparent on the interface somehow.
        qDebug() << "Can't open savedGameFile.";
        return;
    }
    else
    {
        QTextStream in(&savedGameFile);
        QStringList strings;

        long numberOfGames = in.readLine().toLongLong();
        qDebug() << "Loaded" << numberOfGames << "games.";

        // Remove all the games.
        savedGameModel->clear();

        // Add the games from the saves.sav file.
        while (!in.atEnd())
        {
            strings = in.readLine().split("/", QString::KeepEmptyParts);

            // Add the games to the list.
            savedGameModel->appendRow(new SavedGame(strings[0],
                                 strings[3],
                                 strings[4],
                                 strings[1].toLongLong(),
                                 strings[2].toLongLong()));
        }
    }

    // It's important to always close the file after reading/writing, so this
    // app can remain running while Timber and Stone saves as it wishes.
    savedGameFile.close();
}

void SavesAccess::setSavedGameListModel(SavedGameListModel * model)
{
    savedGameModel = model;
}

QByteArray SavesAccess::toBinary(long value)
{
    QByteArray bytes;

    // NOTE: I do not understand this. I understand what it's doing, but
    // I have no idea why. I suspect it's much more simple, and I've
    // missed something.
    if (value>1919) // this is the largest two-byte number
    {
        bytes.append( (((value>>6) + 2)>>6) | 0xe0 );
        bytes.append( (((value>>6) + 2) &0x3f) | 0x80 );
    }
    else
    {
        bytes.append( (((value>>6) &0x1f) + 2) | 0xc0 );
    }
    bytes.append(value&0x3f | 0x80);

    return bytes;
}

// This format handling can certainly be simplified. There's little
// chance that the game designer made it complicated on purpose.
//
long SavesAccess::toLong(QByteArray bytes)
{
    // Ensure the bytes have only their relevant bits visible.
    long value;
    if( bytes.size() > 2 )
    {
        bytes[0] = bytes[0] & 0x1f; // Two or more bytes exist, so this one has an extra id bit.
        bytes[1] = bytes[1] & 0x3f;
        bytes[2] = bytes[2] & 0x3f;

        // Compile the bytes into a long.
        //
        // Note: The -2 in the equation is strange. I have no answer as to why
        // this format requires that.
        value = bytes[2] | (((bytes[1] | (bytes[0]<<6)) -2) << 6);
    }
    else
    {
        bytes[0] = bytes[0] & 0x3f;
        bytes[1] = bytes[1] & 0x3f;
        value = bytes[1] | (bytes[0] -2) << 6;
    }

    return value;
}

// =====================
// RESOURCES
// =====================

void SavesAccess::setResourceListModel(ResourceListModel * model)
{
    resourceModel = model;
}

void SavesAccess::loadResourceFile()
{
    QFile resourceFile(rootSavesDirectory.absolutePath()
                       + "/" + selectedSaveName
                       + "/" + "re.sav");

    if (resourceModel == Q_NULLPTR)
    {
        qDebug() << "Resource model hasn't been set up yet.";
        return;
    }

    // Open file and make sure it went okay.
    if (!resourceFile.exists() || !resourceFile.open(QFile::ReadWrite))
    {
        // TODO: Make this error apparent on the interface somehow.
        qDebug() << "Can't open resourceFile.";
        return;
    }
    else
    {

        // Pull in the list of resource assets (name, group, etc)
        QFile assetFile(QCoreApplication::applicationDirPath() + "/resource_list.csv");

        if (assetFile.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            qDebug() << "Opened Asset File: " << assetFile.fileName();

            // Clear the resource model
            resourceModel->clear();

            QTextStream assetStream(&assetFile);
            long index(0);

            while (!assetStream.atEnd())
            {
                // Grab the next section and decide the size, etc.
                QString assetString;
                assetString = assetStream.readLine();
                QStringList assetData;
                assetData = assetString.split(',');

                // Temporary array to hold the bytes we read from the file.
                QByteArray byteArray;
                byteArray.clear();

                unsigned char byte; // Most Significant Byte
                resourceFile.read((char *)&byte, 1);

                if( byte >= 0xe0)
                {
                    byteArray.append(byte);

                    // Another byte exists!
                    resourceFile.read((char *)&byte, 1);
                    byteArray.append(byte);
                }
                else
                {
                    byteArray.append(byte);
                }

                resourceFile.read((char *)&byte, 1);
                byteArray.append(byte);

                resourceModel->appendRow(new Resource(assetData[0],
                                          assetData[1],
                                          assetData[2],
                                          toLong(byteArray), // resource quantity
                                          index++));         // id
            }

            if (!resourceFile.atEnd())
            {
                // Read the rest of the file into an array, and keep it for later.
                resourceExtraData.clear();
                resourceExtraData = resourceFile.readAll();
            }
        }
        else
        {
            // TODO: Make this error apparent on the interface somehow.
            qDebug() << "Could not open " << assetFile.fileName();
        }

        assetFile.close();
        resourceFile.close();
    }

}

void SavesAccess::saveResourceFile()
{
    if (resourceModel == Q_NULLPTR
            || resourceModel->rowCount() <= 0)
    {
        qDebug() << "The resource model hasn't been populated.";
        return;
    }

    QFile resourceFile(rootSavesDirectory.absolutePath()
                       + "/" + selectedSaveName
                       + "/" + "re.sav");

    // Open file for write, and make sure it went okay.
    if (!resourceFile.open(QFile::ReadWrite))
    {
        // TODO: Make this error apparent on the interface somehow.
        // Perhaps by making the save icon be red instead of green.
        qDebug() << "Can't open resourceFile for writing.";
        return;
    }
    else
    {
        QByteArray binaryData;

        // Write the data to the resource file. Clobber the old one.
        for (int ndx = 0;
             ndx < resourceModel->rowCount();
             ndx++)
        {
            long quantity = resourceModel->index(ndx).data(Resource::QuantityRole).toLongLong();
            if (quantity > 30000)
            {
                qDebug() << "Resource quantities above 32,639 will fail to load in the game. Reduced to 30,000.";
                quantity = 30000;

                // Update the resource.
                resourceModel->setData(ndx,30000);
            }
            binaryData = toBinary(quantity);
            resourceFile.write(binaryData);
        }

        // Write out the unexpected data to the file too.
        resourceFile.write(resourceExtraData);
        resourceFile.close();
    }
}

// =====================
// UNITS (human, neutral mobs, violent mobs)
// =====================

void SavesAccess::setHumanModel(HumanListModel * model)
{
    humanModel = model;
}
void SavesAccess::setNeutralMobModel(NeutralMobListModel * model)
{
    neutralMobModel = model;
}
void SavesAccess::setViolentMobModel(ViolentMobListModel * model)
{
    violentMobModel = model;
}

void SavesAccess::loadUnitFile()
{
    // Compose the file name.
    QFile unitFile(rootSavesDirectory.absolutePath()
                   + "/" + selectedSaveName
                   + "/" + "un.sav");
}

void SavesAccess::saveUnitFile()
{
    // TODO: Save the units to the saved game file.
}

Q_DECLARE_METATYPE(SavesAccess*)
<commit_msg>Added more stuff.<commit_after>#include "savesaccess.h"

#include <QtWidgets/QApplication>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QWidget>
#include <QDebug>

SavesAccess::SavesAccess(QObject *parent) :
    QObject(parent),
    savedGameModel(Q_NULLPTR),
    resourceModel(Q_NULLPTR)
{
}

// Sets the path and loads the game.
void SavesAccess::loadSavedGame(QString gameName)
{
    // Set the game name.
    selectedSaveName = gameName;

    // Pull the resources into the list.
    loadResourceFile();
    loadUnitFile();
}

void SavesAccess::saveSavedGame()
{
    saveResourceFile();
    //saveUnitsToFile();
    //saveTimeToFile();
    //saveGameOverviewToFile();
}

void SavesAccess::openFileDialog()
{

    // TODO: Set the parent of this dialog so it returns properly.
    // Not sure if this is the cause of the weird Windows behavior
    // or not. Something to try.
    QFileDialog fileDialog(0,"Timber and Stone saves.sav file");
    fileDialog.setDirectory(rootSavesDirectory);
    fileDialog.setNameFilter("Saves File (saves.sav)");

    // Open the file dialog so the user can select the saves.sav file.
    if (fileDialog.exec())
    {
        rootSavesDirectory.setPath(fileDialog.selectedFiles().first());
        rootSavesDirectory.cdUp(); // This trims off the saves.sav file.
    }
}

// NOTE: Qml access this for types that are explicitly typed in.
void SavesAccess::setFilePath(QString path)
{
    // Save the path to the file.
    rootSavesDirectory.setPath(path);
    rootSavesDirectory.cdUp();
}

QString SavesAccess::getSavesPath()
{
    return (rootSavesDirectory.absolutePath() + "/" + "saves.sav");
}

bool SavesAccess::pathIsValid()
{
    // Return True if both the directory path is valid
    // and the saves.sav file exists.
    QFile savedGameFile(getSavesPath());
    QFileInfo fileInfo(savedGameFile);
    if (savedGameFile.exists() && (fileInfo.fileName() == "saves.sav"))
    {
        return true;
    }
    else
    {
        return false;
    }
}

void SavesAccess::loadGamesList()
{
    // Save the file name.
    QFile savedGameFile(rootSavesDirectory.absolutePath()
                        + "/" + "saves.sav");

    if (savedGameModel == Q_NULLPTR)
    {
        qDebug() << "SavedAccess model hasn't been set up yet.";
        return;
    }

    // Open file and make sure it went okay.
    if (!savedGameFile.exists() || !savedGameFile.open(QFile::ReadOnly | QFile::Text))
    {
        // TODO: Make this error apparent on the interface somehow.
        qDebug() << "Can't open savedGameFile.";
        return;
    }
    else
    {
        QTextStream in(&savedGameFile);
        QStringList strings;

        long numberOfGames = in.readLine().toLongLong();
        qDebug() << "Loaded" << numberOfGames << "games.";

        // Remove all the games.
        savedGameModel->clear();

        // Add the games from the saves.sav file.
        while (!in.atEnd())
        {
            strings = in.readLine().split("/", QString::KeepEmptyParts);

            // Add the games to the list.
            savedGameModel->appendRow(new SavedGame(strings[0],
                                 strings[3],
                                 strings[4],
                                 strings[1].toLongLong(),
                                 strings[2].toLongLong()));
        }
    }

    // It's important to always close the file after reading/writing, so this
    // app can remain running while Timber and Stone saves as it wishes.
    savedGameFile.close();
}

void SavesAccess::setSavedGameListModel(SavedGameListModel * model)
{
    savedGameModel = model;
}

QByteArray SavesAccess::toBinary(long value)
{
    QByteArray bytes;

    // NOTE: I do not understand this. I understand what it's doing, but
    // I have no idea why. I suspect it's much more simple, and I've
    // missed something.
    if (value>1919) // this is the largest two-byte number
    {
        bytes.append( (((value>>6) + 2)>>6) | 0xe0 );
        bytes.append( (((value>>6) + 2) &0x3f) | 0x80 );
    }
    else
    {
        bytes.append( (((value>>6) &0x1f) + 2) | 0xc0 );
    }
    bytes.append((value&0x3f) | 0x80);

    return bytes;
}

// This format handling can certainly be simplified. There's little
// chance that the game designer made it complicated on purpose.
//
long SavesAccess::toLong(QByteArray bytes)
{
    // Ensure the bytes have only their relevant bits visible.
    long value;
    if( bytes.size() > 2 )
    {
        bytes[0] = bytes[0] & 0x1f; // Two or more bytes exist, so this one has an extra id bit.
        bytes[1] = bytes[1] & 0x3f;
        bytes[2] = bytes[2] & 0x3f;

        // Compile the bytes into a long.
        //
        // Note: The -2 in the equation is strange. I have no answer as to why
        // this format requires that.
        value = bytes[2] | (((bytes[1] | (bytes[0]<<6)) -2) << 6);
    }
    else
    {
        bytes[0] = bytes[0] & 0x3f;
        bytes[1] = bytes[1] & 0x3f;
        value = bytes[1] | (bytes[0] -2) << 6;
    }

    return value;
}

// =====================
// RESOURCES
// =====================

void SavesAccess::setResourceListModel(ResourceListModel * model)
{
    resourceModel = model;
}

void SavesAccess::loadResourceFile()
{
    QFile resourceFile(rootSavesDirectory.absolutePath()
                       + "/" + selectedSaveName
                       + "/" + "re.sav");

    if (resourceModel == Q_NULLPTR)
    {
        qDebug() << "Resource model hasn't been set up yet.";
        return;
    }

    // Open file and make sure it went okay.
    if (!resourceFile.exists() || !resourceFile.open(QFile::ReadWrite))
    {
        // TODO: Make this error apparent on the interface somehow.
        qDebug() << "Can't open resourceFile.";
        return;
    }
    else
    {

        // Pull in the list of resource assets (name, group, etc)
        QFile assetFile(QCoreApplication::applicationDirPath() + "/resource_list.csv");

        if (assetFile.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            qDebug() << "Opened Asset File: " << assetFile.fileName();

            // Clear the resource model
            resourceModel->clear();

            QTextStream assetStream(&assetFile);
            long index(0);

            while (!assetStream.atEnd())
            {
                // Grab the next section and decide the size, etc.
                QString assetString;
                assetString = assetStream.readLine();
                QStringList assetData;
                assetData = assetString.split(',');

                // Temporary array to hold the bytes we read from the file.
                QByteArray byteArray;
                byteArray.clear();

                unsigned char byte; // Most Significant Byte
                resourceFile.read((char *)&byte, 1);

                if( byte >= 0xe0)
                {
                    byteArray.append(byte);

                    // Another byte exists!
                    resourceFile.read((char *)&byte, 1);
                    byteArray.append(byte);
                }
                else
                {
                    byteArray.append(byte);
                }

                resourceFile.read((char *)&byte, 1);
                byteArray.append(byte);

                resourceModel->appendRow(new Resource(assetData[0],
                                          assetData[1],
                                          assetData[2],
                                          toLong(byteArray), // resource quantity
                                          index++));         // id
            }

            if (!resourceFile.atEnd())
            {
                // Read the rest of the file into an array, and keep it for later.
                resourceExtraData.clear();
                resourceExtraData = resourceFile.readAll();
            }
        }
        else
        {
            // TODO: Make this error apparent on the interface somehow.
            qDebug() << "Could not open " << assetFile.fileName();
        }

        assetFile.close();
        resourceFile.close();
    }

}

void SavesAccess::saveResourceFile()
{
    if (resourceModel == Q_NULLPTR
            || resourceModel->rowCount() <= 0)
    {
        qDebug() << "The resource model hasn't been populated.";
        return;
    }

    QFile resourceFile(rootSavesDirectory.absolutePath()
                       + "/" + selectedSaveName
                       + "/" + "re.sav");

    // Open file for write, and make sure it went okay.
    if (!resourceFile.open(QFile::ReadWrite))
    {
        // TODO: Make this error apparent on the interface somehow.
        // Perhaps by making the save icon be red instead of green.
        qDebug() << "Can't open resourceFile for writing.";
        return;
    }
    else
    {
        QByteArray binaryData;

        // Write the data to the resource file. Clobber the old one.
        for (int ndx = 0;
             ndx < resourceModel->rowCount();
             ndx++)
        {
            long quantity = resourceModel->index(ndx).data(Resource::QuantityRole).toLongLong();
            if (quantity > 30000)
            {
                qDebug() << "Resource quantities above 32,639 will fail to load in the game. Reduced to 30,000.";
                quantity = 30000;

                // Update the resource.
                resourceModel->setData(ndx,30000);
            }
            binaryData = toBinary(quantity);
            resourceFile.write(binaryData);
        }

        // Write out the unexpected data to the file too.
        resourceFile.write(resourceExtraData);
        resourceFile.close();
    }
}

// =====================
// UNITS (human, neutral mobs, violent mobs)
// =====================

void SavesAccess::setHumanModel(HumanListModel * model)
{
    humanModel = model;
}
void SavesAccess::setNeutralMobModel(NeutralMobListModel * model)
{
    neutralMobModel = model;
}
void SavesAccess::setViolentMobModel(ViolentMobListModel * model)
{
    violentMobModel = model;
}

void SavesAccess::loadUnitFile()
{
    // Compose the file name.
    QFile unitFile(rootSavesDirectory.absolutePath()
                   + "/" + selectedSaveName
                   + "/" + "un.sav");

    if ((humanModel == Q_NULLPTR) |
        (neutralMobModel == Q_NULLPTR) |
        (violentMobModel == Q_NULLPTR) )
    {
        qDebug() << "Human, neutral, violent mob models haven't been set up yet.";
        return;
    }

    // Open file and make sure it went okay.
    if (!unitFile.exists() || !unitFile.open(QFile::ReadWrite))
    {
        // TODO: Make this error apparent on the interface somehow.
        qDebug() << "Can't open unitFile.";
        return;
    }
    else
    {
        qDebug() << "Opened unitFile." << unitFile.fileName();

        // Remove all the humans.
        humanModel->clear();

        QTextStream unitStream(&unitFile);
        QString unitString;
        QStringList unitData;

        // Load in all the Humans
        int numberOfHumans = unitStream.readLine().toInt();
        qDebug() << "Number of humans: " << numberOfHumans;
        for (int i=0; i<numberOfHumans; i++)
        {
            unitString = unitStream.readLine();
            unitData = unitString.split('/');
            qDebug() << "   " << unitData[0];

            humanModel->appendRow(new Human(unitData[4],
                                  unitData[0],
                                  i));
        }
        qDebug() << "In model: " << humanModel->rowCount();

        // Load in all the Neutral Mobs
        int numberOfNeutralMobs = unitStream.readLine().toInt();
        qDebug() << "Number of neutral mobs: " << numberOfNeutralMobs;
        for (int i=0; i<numberOfNeutralMobs; i++)
        {
            unitString = unitStream.readLine();
            unitData = unitString.split('/');

            qDebug() << "   " << unitData[0];
        }

        // Load in all the Violent Mobs
        int numberOfViolentMobs = unitStream.readLine().toInt();
        qDebug() << "Number of violent mobs: " << numberOfViolentMobs;
        for (int i=0; i<numberOfViolentMobs; i++)
        {
            unitString = unitStream.readLine();
            unitData = unitString.split('/');

            qDebug() << "   " << unitData[0];
        }

        unitFile.close();
    }

}

void SavesAccess::saveUnitFile()
{
    // TODO: Save the units to the saved game file.
}

Q_DECLARE_METATYPE(SavesAccess*)
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "LocalizedStrings.h"
#include "PlatformString.h"
#include "IntSize.h"

#undef LOG
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webkit_glue.h"
#include "base/logging.h"
#include "base/file_util.h"
#include "base/string_util.h"
#include "build/build_config.h"
#include "webkit/glue/glue_util.h"

#if defined(OS_WIN)
#include "webkit_strings.h"
#else
// TODO:(pinkerton): only windows has the GRIT machinery, so we've created a
// temporary generated header until we can figure out the l10n strategy.
#include "bogus_webkit_strings.h"
#endif

using namespace WebCore;

inline String GetLocalizedString(int message_id) {
  const std::wstring& str(webkit_glue::GetLocalizedString(message_id));
  return webkit_glue::StdWStringToString(str);
}

#if defined(OS_WIN)
String WebCore::searchableIndexIntroduction() {
  return GetLocalizedString(IDS_SEARCHABLE_INDEX_INTRO);
}
String WebCore::submitButtonDefaultLabel() {
  return GetLocalizedString(IDS_FORM_SUBMIT_LABEL);
}
String WebCore::inputElementAltText() {
  return GetLocalizedString(IDS_FORM_INPUT_ALT);
}
String WebCore::resetButtonDefaultLabel() {
  return GetLocalizedString(IDS_FORM_RESET_LABEL);
}
String WebCore::fileButtonChooseFileLabel() {
  return GetLocalizedString(IDS_FORM_FILE_BUTTON_LABEL);
}
String WebCore::fileButtonNoFileSelectedLabel() {
  return GetLocalizedString(IDS_FORM_FILE_NO_FILE_LABEL);
}

String WebCore::searchMenuNoRecentSearchesText() {
  return GetLocalizedString(IDS_RECENT_SEARCHES_NONE);
}
String WebCore::searchMenuRecentSearchesText() {
  return GetLocalizedString(IDS_RECENT_SEARCHES);
}
String WebCore::searchMenuClearRecentSearchesText() {
  return GetLocalizedString(IDS_RECENT_SEARCHES_CLEAR);
}

// A11y strings.
String WebCore::AXWebAreaText() {
  return GetLocalizedString(IDS_AX_ROLE_WEB_AREA);
}
String WebCore::AXLinkText() {
  return GetLocalizedString(IDS_AX_ROLE_LINK);
}
String WebCore::AXListMarkerText() {
  return GetLocalizedString(IDS_AX_ROLE_LIST_MARKER);
}
String WebCore::AXImageMapText() {
  return GetLocalizedString(IDS_AX_ROLE_IMAGE_MAP);
}
String WebCore::AXHeadingText() {
  return GetLocalizedString(IDS_AX_ROLE_HEADING);
}
#endif  // OS_WIN
String WebCore::AXButtonActionVerb() {
  return GetLocalizedString(IDS_AX_BUTTON_ACTION_VERB);
}
String WebCore::AXRadioButtonActionVerb() {
  return GetLocalizedString(IDS_AX_RADIO_BUTTON_ACTION_VERB);
}
String WebCore::AXTextFieldActionVerb() {
  return GetLocalizedString(IDS_AX_TEXT_FIELD_ACTION_VERB);
}
String WebCore::AXCheckedCheckBoxActionVerb() {
  return GetLocalizedString(IDS_AX_CHECKED_CHECK_BOX_ACTION_VERB);
}
String WebCore::AXUncheckedCheckBoxActionVerb() {
  return GetLocalizedString(IDS_AX_UNCHECKED_CHECK_BOX_ACTION_VERB);
}
String WebCore::AXLinkActionVerb() {
  return GetLocalizedString(IDS_AX_LINK_ACTION_VERB);
}

// Used in FTPDirectoryDocument.cpp
String WebCore::unknownFileSizeText() {
  return String();
}

// These two are used in FileChooserWin.cpp.
#if PLATFORM(WIN)
String WebCore::uploadFileText() {
  return String();
}
String WebCore::allFilesText() {
  return String();
}
#endif

// The following two functions are not declared in LocalizedStrings.h.
// They are used by the menu for the HTML keygen tag.
namespace WebCore {
String keygenMenuHighGradeKeySize() {
  return GetLocalizedString(IDS_KEYGEN_HIGH_GRADE_KEY);
}
String keygenMenuMediumGradeKeySize() {
  return GetLocalizedString(IDS_KEYGEN_MED_GRADE_KEY);
}

// Used in ImageDocument.cpp as the title for pages when that page is an image.
String imageTitle(const String& filename, const IntSize& size) {
  // C3 97 is UTF-8 for U+00D7 (multiplication sign).
  std::string size_str = StringPrintf(" (%d\xC3\x97%d)",
                                      size.width(), size.height());
  return filename + webkit_glue::StdStringToString(size_str);
}

} //namespace WebCore

#if defined(OS_WIN)
// We don't use these strings, so they return an empty String. We can't just
// make them asserts because webcore still calls them.
String WebCore::contextMenuItemTagOpenLinkInNewWindow() { return String(); }
String WebCore::contextMenuItemTagDownloadLinkToDisk() { return String(); }
String WebCore::contextMenuItemTagCopyLinkToClipboard() { return String(); }
String WebCore::contextMenuItemTagOpenImageInNewWindow() { return String(); }
String WebCore::contextMenuItemTagDownloadImageToDisk() { return String(); }
String WebCore::contextMenuItemTagCopyImageToClipboard() { return String(); }
String WebCore::contextMenuItemTagOpenFrameInNewWindow() { return String(); }
String WebCore::contextMenuItemTagCopy() { return String(); }
String WebCore::contextMenuItemTagGoBack() { return String(); }
String WebCore::contextMenuItemTagGoForward() { return String(); }
String WebCore::contextMenuItemTagStop() { return String(); }
String WebCore::contextMenuItemTagReload() { return String(); }
String WebCore::contextMenuItemTagCut() { return String(); }
String WebCore::contextMenuItemTagPaste() { return String(); }
String WebCore::contextMenuItemTagNoGuessesFound() { return String(); }
String WebCore::contextMenuItemTagIgnoreSpelling() { return String(); }
String WebCore::contextMenuItemTagLearnSpelling() { return String(); }
String WebCore::contextMenuItemTagSearchWeb() { return String(); }
String WebCore::contextMenuItemTagLookUpInDictionary() { return String(); }
String WebCore::contextMenuItemTagOpenLink() { return String(); }
String WebCore::contextMenuItemTagIgnoreGrammar() { return String(); }
String WebCore::contextMenuItemTagSpellingMenu() { return String(); }
String WebCore::contextMenuItemTagCheckSpelling() { return String(); }
String WebCore::contextMenuItemTagCheckSpellingWhileTyping() { return String(); }
String WebCore::contextMenuItemTagCheckGrammarWithSpelling() { return String(); }
String WebCore::contextMenuItemTagFontMenu() { return String(); }
String WebCore::contextMenuItemTagBold() { return String(); }
String WebCore::contextMenuItemTagItalic() { return String(); }
String WebCore::contextMenuItemTagUnderline() { return String(); }
String WebCore::contextMenuItemTagOutline() { return String(); }
String WebCore::contextMenuItemTagWritingDirectionMenu() { return String(); }
String WebCore::contextMenuItemTagDefaultDirection() { return String(); }
String WebCore::contextMenuItemTagLeftToRight() { return String(); }
String WebCore::contextMenuItemTagRightToLeft() { return String(); }
String WebCore::contextMenuItemTagInspectElement() { return String(); }
String WebCore::contextMenuItemTagShowSpellingPanel(bool show) { return String(); }
#endif  // OS_WIN
<commit_msg>We want these symbols on all platforms.<commit_after>/*
 * Copyright (C) 2007 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "LocalizedStrings.h"
#include "PlatformString.h"
#include "IntSize.h"

#undef LOG
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webkit_glue.h"
#include "base/logging.h"
#include "base/file_util.h"
#include "base/string_util.h"
#include "build/build_config.h"
#include "webkit/glue/glue_util.h"

#if defined(OS_WIN)
#include "webkit_strings.h"
#else
// TODO:(pinkerton): only windows has the GRIT machinery, so we've created a
// temporary generated header until we can figure out the l10n strategy.
#include "bogus_webkit_strings.h"
#endif

using namespace WebCore;

inline String GetLocalizedString(int message_id) {
  const std::wstring& str(webkit_glue::GetLocalizedString(message_id));
  return webkit_glue::StdWStringToString(str);
}

String WebCore::searchableIndexIntroduction() {
  return GetLocalizedString(IDS_SEARCHABLE_INDEX_INTRO);
}
String WebCore::submitButtonDefaultLabel() {
  return GetLocalizedString(IDS_FORM_SUBMIT_LABEL);
}
String WebCore::inputElementAltText() {
  return GetLocalizedString(IDS_FORM_INPUT_ALT);
}
String WebCore::resetButtonDefaultLabel() {
  return GetLocalizedString(IDS_FORM_RESET_LABEL);
}
String WebCore::fileButtonChooseFileLabel() {
  return GetLocalizedString(IDS_FORM_FILE_BUTTON_LABEL);
}
String WebCore::fileButtonNoFileSelectedLabel() {
  return GetLocalizedString(IDS_FORM_FILE_NO_FILE_LABEL);
}

String WebCore::searchMenuNoRecentSearchesText() {
  return GetLocalizedString(IDS_RECENT_SEARCHES_NONE);
}
String WebCore::searchMenuRecentSearchesText() {
  return GetLocalizedString(IDS_RECENT_SEARCHES);
}
String WebCore::searchMenuClearRecentSearchesText() {
  return GetLocalizedString(IDS_RECENT_SEARCHES_CLEAR);
}

// A11y strings.
String WebCore::AXWebAreaText() {
  return GetLocalizedString(IDS_AX_ROLE_WEB_AREA);
}
String WebCore::AXLinkText() {
  return GetLocalizedString(IDS_AX_ROLE_LINK);
}
String WebCore::AXListMarkerText() {
  return GetLocalizedString(IDS_AX_ROLE_LIST_MARKER);
}
String WebCore::AXImageMapText() {
  return GetLocalizedString(IDS_AX_ROLE_IMAGE_MAP);
}
String WebCore::AXHeadingText() {
  return GetLocalizedString(IDS_AX_ROLE_HEADING);
}
String WebCore::AXButtonActionVerb() {
  return GetLocalizedString(IDS_AX_BUTTON_ACTION_VERB);
}
String WebCore::AXRadioButtonActionVerb() {
  return GetLocalizedString(IDS_AX_RADIO_BUTTON_ACTION_VERB);
}
String WebCore::AXTextFieldActionVerb() {
  return GetLocalizedString(IDS_AX_TEXT_FIELD_ACTION_VERB);
}
String WebCore::AXCheckedCheckBoxActionVerb() {
  return GetLocalizedString(IDS_AX_CHECKED_CHECK_BOX_ACTION_VERB);
}
String WebCore::AXUncheckedCheckBoxActionVerb() {
  return GetLocalizedString(IDS_AX_UNCHECKED_CHECK_BOX_ACTION_VERB);
}
String WebCore::AXLinkActionVerb() {
  return GetLocalizedString(IDS_AX_LINK_ACTION_VERB);
}

// Used in FTPDirectoryDocument.cpp
String WebCore::unknownFileSizeText() {
  return String();
}

// These two are used in FileChooserWin.cpp.
#if PLATFORM(WIN)
String WebCore::uploadFileText() {
  return String();
}
String WebCore::allFilesText() {
  return String();
}
#endif

// The following two functions are not declared in LocalizedStrings.h.
// They are used by the menu for the HTML keygen tag.
namespace WebCore {
String keygenMenuHighGradeKeySize() {
  return GetLocalizedString(IDS_KEYGEN_HIGH_GRADE_KEY);
}
String keygenMenuMediumGradeKeySize() {
  return GetLocalizedString(IDS_KEYGEN_MED_GRADE_KEY);
}

// Used in ImageDocument.cpp as the title for pages when that page is an image.
String imageTitle(const String& filename, const IntSize& size) {
  // C3 97 is UTF-8 for U+00D7 (multiplication sign).
  std::string size_str = StringPrintf(" (%d\xC3\x97%d)",
                                      size.width(), size.height());
  return filename + webkit_glue::StdStringToString(size_str);
}

} //namespace WebCore

// We don't use these strings, so they return an empty String. We can't just
// make them asserts because webcore still calls them.
String WebCore::contextMenuItemTagOpenLinkInNewWindow() { return String(); }
String WebCore::contextMenuItemTagDownloadLinkToDisk() { return String(); }
String WebCore::contextMenuItemTagCopyLinkToClipboard() { return String(); }
String WebCore::contextMenuItemTagOpenImageInNewWindow() { return String(); }
String WebCore::contextMenuItemTagDownloadImageToDisk() { return String(); }
String WebCore::contextMenuItemTagCopyImageToClipboard() { return String(); }
String WebCore::contextMenuItemTagOpenFrameInNewWindow() { return String(); }
String WebCore::contextMenuItemTagCopy() { return String(); }
String WebCore::contextMenuItemTagGoBack() { return String(); }
String WebCore::contextMenuItemTagGoForward() { return String(); }
String WebCore::contextMenuItemTagStop() { return String(); }
String WebCore::contextMenuItemTagReload() { return String(); }
String WebCore::contextMenuItemTagCut() { return String(); }
String WebCore::contextMenuItemTagPaste() { return String(); }
String WebCore::contextMenuItemTagNoGuessesFound() { return String(); }
String WebCore::contextMenuItemTagIgnoreSpelling() { return String(); }
String WebCore::contextMenuItemTagLearnSpelling() { return String(); }
String WebCore::contextMenuItemTagSearchWeb() { return String(); }
String WebCore::contextMenuItemTagLookUpInDictionary() { return String(); }
String WebCore::contextMenuItemTagOpenLink() { return String(); }
String WebCore::contextMenuItemTagIgnoreGrammar() { return String(); }
String WebCore::contextMenuItemTagSpellingMenu() { return String(); }
String WebCore::contextMenuItemTagCheckSpelling() { return String(); }
String WebCore::contextMenuItemTagCheckSpellingWhileTyping() { return String(); }
String WebCore::contextMenuItemTagCheckGrammarWithSpelling() { return String(); }
String WebCore::contextMenuItemTagFontMenu() { return String(); }
String WebCore::contextMenuItemTagBold() { return String(); }
String WebCore::contextMenuItemTagItalic() { return String(); }
String WebCore::contextMenuItemTagUnderline() { return String(); }
String WebCore::contextMenuItemTagOutline() { return String(); }
String WebCore::contextMenuItemTagWritingDirectionMenu() { return String(); }
String WebCore::contextMenuItemTagDefaultDirection() { return String(); }
String WebCore::contextMenuItemTagLeftToRight() { return String(); }
String WebCore::contextMenuItemTagRightToLeft() { return String(); }
String WebCore::contextMenuItemTagInspectElement() { return String(); }
String WebCore::contextMenuItemTagShowSpellingPanel(bool show) { return String(); }
<|endoftext|>


<commit_before>#ifndef slic3r_Tesselate_hpp_
#define slic3r_Tesselate_hpp_

#include <vector>

namespace Slic3r {

class ExPolygon;
typedef std::vector<ExPolygon> ExPolygons;

extern Pointf3s triangulate_expolygons_3df(const ExPolygon &poly, coordf_t z = 0, bool flip = false);
extern Pointf3s triangulate_expolygons_3df(const ExPolygons &polys, coordf_t z = 0, bool flip = false);

} // namespace Slic3r

#endif /* slic3r_Tesselate_hpp_ */
<commit_msg>Fixed compilation on OSX<commit_after>#ifndef slic3r_Tesselate_hpp_
#define slic3r_Tesselate_hpp_

#include <vector>

#include "Point.hpp"

namespace Slic3r {

class ExPolygon;
typedef std::vector<ExPolygon> ExPolygons;

extern Pointf3s triangulate_expolygons_3df(const ExPolygon &poly, coordf_t z = 0, bool flip = false);
extern Pointf3s triangulate_expolygons_3df(const ExPolygons &polys, coordf_t z = 0, bool flip = false);

} // namespace Slic3r

#endif /* slic3r_Tesselate_hpp_ */
<|endoftext|>


<commit_before>#include "graphwidget.h"

#include <QGraphicsScene>
#include <QGraphicsPolygonItem>
#include <QWheelEvent>
#include <QApplication>
#include <QUrl>

#include "sprite.h"
#include "config.h"
#include "Debug.h"

GraphWidget::GraphWidget(QWidget *parent)
    : QGraphicsView(parent)
    , m_scene(new QGraphicsScene())
    , m_scaleFactor(1)
    , m_pressed(false)
{
    QSettings settings(Config::config(), Config::format());
    int w = settings.value(Config::editorw, Config::w).toReal();
    int h = settings.value(Config::editorh, Config::h).toReal();

    this->setScene(m_scene);
    this->setSceneRect(0,0,w,h);

    init();
//    m_scene->addRect(0,0,w,h, QPen(Qt::red, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin));

    setUpright(false, iPhone480x320);
}

void GraphWidget::scaleBy(double factor)
{
    scale(factor, factor);
}

void GraphWidget::zoomIn()
{
    scaleBy(1.1);
}

void GraphWidget::zoomOut()
{
    scaleBy(1.0 / 1.1);
}

void GraphWidget::setUpright(bool yes, DeviceType type)
{
    if (yes) {
        m_bgFrame.load(m_frames.value(type));
        m_frameStartPoint = m_framePoint.value(type);
    }
    else {
        m_bgFrame.load(m_framevs.value(type));
        m_frameStartPoint = m_framevPoint.value(type);
    }
}

void GraphWidget::init()
{
    m_frames.insert(iPhone480x320, "resource/4frame.png");
    m_frames.insert(iPhone960x640, "resource/fframe@2x.png");

    m_framevs.insert(iPhone480x320, "resource/4frame-v.png");
    m_framevs.insert(iPhone960x640, "resource/fframe@2x-v.png");

    m_framePoint.insert(iPhone480x320, QPoint(0,0));
    m_framePoint.insert(iPhone480x320, QPoint(0,0));

    m_framevPoint.insert(iPhone480x320, QPoint(-119,-23));
    m_framevPoint.insert(iPhone960x640, QPoint(0,0));

    // mouse rect
    m_mouseRectItem.setRect(0,0,1,1);
    m_mouseRectItem.setBrush(QBrush(QColor(200,200,200,100)));
    m_mouseRectItem.hide();
    m_mouseRectItem.setZValue(100);
    m_scene->addItem(&m_mouseRectItem);

    // controller
    m_controllerItem.setRect(0,0,100,100);
    m_controllerItem.setBrush(QBrush(QColor(255,0,0,100)));
    m_controllerItem.hide();
    m_controllerItem.setZValue(100);
    m_scene->addItem(&m_controllerItem);
}

void GraphWidget::wheelEvent(QWheelEvent *event)
{
    if (event->modifiers() == Qt::ControlModifier)
     {
         scaleBy(std::pow(4.0 / 3.0, (-event->delta() / 240.0)));
     }
     else
     {
         QGraphicsView::wheelEvent(event);
     }

    QGraphicsView::wheelEvent(event);
}

/**
 * @brief GraphWidget::mousePressEvent
 * @param event
 *
 * - Operation of object is like folder on windows/mac/..
 */
void GraphWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        QGraphicsItem *item = itemAt(event->pos());

        m_prePos = event->posF();
        m_pressed = true;
        if (item) {
            // add child if pressed ctrl, otherwise set the selected
            // item as selected items
            if (event->modifiers() == Qt::ControlModifier) {
                if (!m_selectItems.contains(item))
                    m_selectItems.append(item);
            } else {
                if (!m_selectItems.contains(item)) {
                    m_selectItems.clear();
                    m_selectItems.append(item);
                }
            }
        } else {
            // clear selected itmes and show mouse rect

            // clear
            m_selectItems.clear();

            // show rect
            m_mouseStartPoint = mapToScene(event->pos());
            m_mouseRectItem.setRect(m_mouseRectItem.x()
                                    , m_mouseRectItem.y(),1,1);
            m_mouseRectItem.show();
        }
    }
    QGraphicsView::mousePressEvent(event);
}

void GraphWidget::mouseReleaseEvent(QMouseEvent * event)
{
    m_pressed = false;

    // select the items which in the mouse rect
    m_selectItems = m_mouseRectItem.collidingItems();

    m_mouseRectItem.hide();
    QGraphicsView::mouseReleaseEvent(event);
}

void GraphWidget::mouseMoveEvent(QMouseEvent *event)
{
    // move items if there are, otherwise show mouse rect
    if (m_pressed) {
        if (m_selectItems.count()) {
            foreach (QGraphicsItem* it, m_selectItems) {
                QPointF delta = event->posF() - m_prePos;
                it->setPos(delta + it->pos());
            }
            m_prePos =event->posF();
        } else {
            QPointF p = mapToScene(event->pos());
            showMouseRect(m_mouseStartPoint.toPoint(), p.toPoint());

        }
    }

    QGraphicsView::mouseMoveEvent(event);
}

void GraphWidget::keyReleaseEvent(QKeyEvent *event)
{
    // delete sprite
    if (event->key() == Qt::Key_Delete) {
        qDeleteAll(m_selectItems);
        m_selectItems.clear();
    }

    QGraphicsView::keyReleaseEvent(event);
}

void GraphWidget::paintEvent(QPaintEvent * event)
{
    QGraphicsView::paintEvent(event);
}

void GraphWidget::dragEnterEvent(QDragEnterEvent *event)
{
    event->accept();
}

void GraphWidget::dragMoveEvent(QDragMoveEvent *event)
{
    event->accept();
}

void GraphWidget::dropEvent(QDropEvent *event)
{
    if (m_scene) {
        QUrl url = event->mimeData()->urls().at(0);
        QString file = url.toLocalFile();
        QPixmap pixmap(file);
        if (!pixmap.isNull()) {
            Sprite *sprite = new Sprite(QPixmap(url.toLocalFile()));
            sprite->setPos(mapToScene(event->pos()));
            m_scene->addItem(sprite);
        } if (file.endsWith(".pshs")) {

        } else if (file.endsWith(".plist")) {

        }
    }
}

void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
{
    QGraphicsView::drawBackground(painter, rect);

    if (!m_bgFrame.isNull()) {
        painter->drawPixmap(m_frameStartPoint, m_bgFrame);
    }
}

void GraphWidget::drawForeground(QPainter *painter, const QRectF &rect)
{
    QGraphicsView::drawForeground(painter, rect);

    // view rect
    painter->setPen(QPen(Qt::red));
    painter->drawRect(sceneRect());
}

void GraphWidget::showMouseRect(QPoint start, QPoint end)
{
    int x = start.x();
    int y = start.y();
    int w = end.x() - start.x();
    int h = end.y() - start.y();

    if (w < 0) x = end.x();
    if (h < 0) y = end.y();

    m_mouseRectItem.setRect(x,y, abs(w),abs(h));
}

void GraphWidget::hideControllerItem()
{
    m_controllerItem.hide();
}

void GraphWidget::showControllerItem(QPointF pos)
{
    m_controllerItem.show();
    m_controllerItem.setPos(pos);
}

void GraphWidget::showControllerItem(QPoint pos)
{
    m_controllerItem.show();
    m_controllerItem.setPos(pos);
}
<commit_msg>[fix:#2] only one move<commit_after>#include "graphwidget.h"

#include <QGraphicsScene>
#include <QGraphicsPolygonItem>
#include <QWheelEvent>
#include <QApplication>
#include <QUrl>

#include "sprite.h"
#include "config.h"
#include "Debug.h"

GraphWidget::GraphWidget(QWidget *parent)
    : QGraphicsView(parent)
    , m_scene(new QGraphicsScene())
    , m_scaleFactor(1)
    , m_pressed(false)
{
    QSettings settings(Config::config(), Config::format());
    int w = settings.value(Config::editorw, Config::w).toReal();
    int h = settings.value(Config::editorh, Config::h).toReal();

    this->setScene(m_scene);
    this->setSceneRect(0,0,w,h);

    init();
//    m_scene->addRect(0,0,w,h, QPen(Qt::red, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin));

    setUpright(false, iPhone480x320);
}

void GraphWidget::scaleBy(double factor)
{
    scale(factor, factor);
}

void GraphWidget::zoomIn()
{
    scaleBy(1.1);
}

void GraphWidget::zoomOut()
{
    scaleBy(1.0 / 1.1);
}

void GraphWidget::setUpright(bool yes, DeviceType type)
{
    if (yes) {
        m_bgFrame.load(m_frames.value(type));
        m_frameStartPoint = m_framePoint.value(type);
    }
    else {
        m_bgFrame.load(m_framevs.value(type));
        m_frameStartPoint = m_framevPoint.value(type);
    }
}

void GraphWidget::init()
{
    m_frames.insert(iPhone480x320, "resource/4frame.png");
    m_frames.insert(iPhone960x640, "resource/fframe@2x.png");

    m_framevs.insert(iPhone480x320, "resource/4frame-v.png");
    m_framevs.insert(iPhone960x640, "resource/fframe@2x-v.png");

    m_framePoint.insert(iPhone480x320, QPoint(0,0));
    m_framePoint.insert(iPhone480x320, QPoint(0,0));

    m_framevPoint.insert(iPhone480x320, QPoint(-119,-23));
    m_framevPoint.insert(iPhone960x640, QPoint(0,0));

    // mouse rect
    m_mouseRectItem.setRect(0,0,1,1);
    m_mouseRectItem.setBrush(QBrush(QColor(200,200,200,100)));
    m_mouseRectItem.hide();
    m_mouseRectItem.setZValue(100);
    m_scene->addItem(&m_mouseRectItem);

    // controller
    m_controllerItem.setRect(0,0,100,100);
    m_controllerItem.setBrush(QBrush(QColor(255,0,0,100)));
    m_controllerItem.hide();
    m_controllerItem.setZValue(100);
    m_scene->addItem(&m_controllerItem);
}

void GraphWidget::wheelEvent(QWheelEvent *event)
{
    if (event->modifiers() == Qt::ControlModifier)
     {
         scaleBy(std::pow(4.0 / 3.0, (-event->delta() / 240.0)));
     }
     else
     {
         QGraphicsView::wheelEvent(event);
     }

    QGraphicsView::wheelEvent(event);
}

/**
 * @brief GraphWidget::mousePressEvent
 * @param event
 *
 * - Operation of object is like folder on windows/mac/..
 */
void GraphWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        QGraphicsItem *item = itemAt(event->pos());

        m_prePos = event->posF();
        m_pressed = true;
        if (item) {
            // add child if pressed ctrl, otherwise set the selected
            // item as selected items
            if (event->modifiers() == Qt::ControlModifier) {
                if (!m_selectItems.contains(item)) {
                    m_selectItems.append(item);
                }

            } else {
                if (!m_selectItems.contains(item)) {
                    m_selectItems.clear();
                    m_selectItems.append(item);
                }
            }
        } else {
            // clear selected itmes and show mouse rect

            // clear
            m_selectItems.clear();

            // show rect
            m_mouseStartPoint = mapToScene(event->pos());
            m_mouseRectItem.setRect(m_mouseRectItem.x()
                                    , m_mouseRectItem.y(),1,1);
        }
    }
    QGraphicsView::mousePressEvent(event);
}

void GraphWidget::mouseReleaseEvent(QMouseEvent * event)
{
    m_pressed = false;

    if (m_mouseRectItem.isVisible()) {
        // select the items which in the mouse rect
        m_selectItems = m_mouseRectItem.collidingItems();
    }

    m_mouseRectItem.hide();
    QGraphicsView::mouseReleaseEvent(event);
}

void GraphWidget::mouseMoveEvent(QMouseEvent *event)
{
    // move items if there are, otherwise show mouse rect
    if (m_pressed) {
        if (m_selectItems.count()) {
            foreach (QGraphicsItem* it, m_selectItems) {
                QPointF delta = event->posF() - m_prePos;
                it->setPos(delta + it->pos());
            }
            m_prePos =event->posF();
        } else {
            QPointF p = mapToScene(event->pos());
            showMouseRect(m_mouseStartPoint.toPoint(), p.toPoint());
        }
    }

    QGraphicsView::mouseMoveEvent(event);
}

void GraphWidget::keyReleaseEvent(QKeyEvent *event)
{
    // delete sprite
    if (event->key() == Qt::Key_Delete) {
        qDeleteAll(m_selectItems);
        m_selectItems.clear();
    }

    QGraphicsView::keyReleaseEvent(event);
}

void GraphWidget::paintEvent(QPaintEvent * event)
{
    QGraphicsView::paintEvent(event);
}

void GraphWidget::dragEnterEvent(QDragEnterEvent *event)
{
    event->accept();
}

void GraphWidget::dragMoveEvent(QDragMoveEvent *event)
{
    event->accept();
}

void GraphWidget::dropEvent(QDropEvent *event)
{
    if (m_scene) {
        QUrl url = event->mimeData()->urls().at(0);
        QString file = url.toLocalFile();
        QPixmap pixmap(file);
        if (!pixmap.isNull()) {
            Sprite *sprite = new Sprite(QPixmap(url.toLocalFile()));
            sprite->setPos(mapToScene(event->pos()));
            m_scene->addItem(sprite);
        } if (file.endsWith(".pshs")) {

        } else if (file.endsWith(".plist")) {

        }
    }
}

void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
{
    QGraphicsView::drawBackground(painter, rect);

    if (!m_bgFrame.isNull()) {
        painter->drawPixmap(m_frameStartPoint, m_bgFrame);
    }
}

void GraphWidget::drawForeground(QPainter *painter, const QRectF &rect)
{
    QGraphicsView::drawForeground(painter, rect);

    // view rect
    painter->setPen(QPen(Qt::red));
    painter->drawRect(sceneRect());
}

void GraphWidget::showMouseRect(QPoint start, QPoint end)
{
    int x = start.x();
    int y = start.y();
    int w = end.x() - start.x();
    int h = end.y() - start.y();

    if (w < 0) x = end.x();
    if (h < 0) y = end.y();

    m_mouseRectItem.show();
    m_mouseRectItem.setRect(x,y, abs(w),abs(h));
}

void GraphWidget::hideControllerItem()
{
    m_controllerItem.hide();
}

void GraphWidget::showControllerItem(QPointF pos)
{
    m_controllerItem.show();
    m_controllerItem.setPos(pos);
}

void GraphWidget::showControllerItem(QPoint pos)
{
    m_controllerItem.show();
    m_controllerItem.setPos(pos);
}
<|endoftext|>


<commit_before>//                                MFEM Example 0
//
// Compile with: make ex0
//
// Sample runs:  ex0
//               ex0 -m ../data/fichera.mesh
//               ex0 -m ../data/square-disc.mesh -o 2
//
// Description: This example code demonstrates the most basic usage of MFEM to
//              define a simple finite element discretization of the Laplace
//              problem -Delta u = 1 with zero Dirichlet boundary conditions.
//              General 2D/3D mesh files and finite element polynomial degrees
//              can be specified by command line options.

#include "mfem.hpp"
#include <fstream>
#include <iostream>

using namespace std;
using namespace mfem;

int main(int argc, char *argv[])
{
   // 1. Parse command line options
   const char *mesh_file = "../data/star.mesh";
   int order = 1;

   OptionsParser args(argc, argv);
   args.AddOption(&mesh_file, "-m", "--mesh", "Mesh file to use.");
   args.AddOption(&order, "-o", "--order", "Finite element polynomial degree");
   args.ParseCheck();

   // 2. Read the mesh from the given mesh file, and refine once uniformly.
   Mesh mesh(mesh_file);
   mesh.UniformRefinement();

   // 3. Define a finite element space on the mesh. Here we use H1 continuous
   //    high-order Lagrange finite elements of the given order.
   H1_FECollection fec(order, mesh.Dimension());
   FiniteElementSpace fespace(&mesh, &fec);
   cout << "Number of unknowns: " << fespace.GetTrueVSize() << endl;

   // 4. Extract the list of all the boundary DOFs. These will be marked as
   //    Dirichlet in order to enforce zero boundary conditions.
   Array<int> boundary_dofs;
   fespace.GetBoundaryTrueDofs(boundary_dofs);

   // 5. Define the solution x as a finite element grid function in fespace. Set
   //    the initial guess to zero, which also sets the boundary conditions.
   GridFunction x(&fespace);
   x = 0.0;

   // 6. Set up the linear form b(.) corresponding to the right-hand side.
   ConstantCoefficient one(1.0);
   LinearForm b(&fespace);
   b.AddDomainIntegrator(new DomainLFIntegrator(one));
   b.Assemble();

   // 7. Set up the bilinear form a(.,.) corresponding to the -Delta operator.
   BilinearForm a(&fespace);
   a.AddDomainIntegrator(new DiffusionIntegrator);
   a.Assemble();

   // 8. Form the linear system A X = B. This includes eliminating boundary
   //    conditions, applying AMR constraints, and other transformations.
   SparseMatrix A;
   Vector B, X;
   a.FormLinearSystem(boundary_dofs, x, b, A, X, B);

   // 9. Solve the system using PCG with symmetric Gauss-Seidel preconditioner.
   GSSmoother M(A);
   PCG(A, M, B, X, 1, 200, 1e-12, 0.0);

   // 10. Recover the solution x as a grid function and save to file. The output
   //     can be viewed using GLVis as follows: "glvis -m mesh.mesh -g sol.gf"
   a.RecoverFEMSolution(X, b, x);
   x.Save("sol.gf");
   mesh.Save("mesh.mesh");

   return 0;
}
<commit_msg>Introduce a failure in a test for testing purpose<commit_after>//                                MFEM Example 0
//
// Compile with: make ex0
//
// Sample runs:  ex0
//               ex0 -m ../data/fichera.mesh
//               ex0 -m ../data/square-disc.mesh -o 2
//
// Description: This example code demonstrates the most basic usage of MFEM to
//              define a simple finite element discretization of the Laplace
//              problem -Delta u = 1 with zero Dirichlet boundary conditions.
//              General 2D/3D mesh files and finite element polynomial degrees
//              can be specified by command line options.

#include "mfem.hpp"
#include <fstream>
#include <iostream>

using namespace std;
using namespace mfem;

int main(int argc, char *argv[])
{
   // 1. Parse command line options
   const char *mesh_file = "../data/star.mesh";
   int order = 1;

   OptionsParser args(argc, argv);
   args.AddOption(&mesh_file, "-m", "--mesh", "Mesh file to use.");
   args.AddOption(&order, "-o", "--order", "Finite element polynomial degree");
   args.ParseCheck();

   // 2. Read the mesh from the given mesh file, and refine once uniformly.
   Mesh mesh(mesh_file);
   mesh.UniformRefinement();

   // 3. Define a finite element space on the mesh. Here we use H1 continuous
   //    high-order Lagrange finite elements of the given order.
   H1_FECollection fec(order, mesh.Dimension());
   FiniteElementSpace fespace(&mesh, &fec);
   cout << "Number of unknowns: " << fespace.GetTrueVSize() << endl;

   // 4. Extract the list of all the boundary DOFs. These will be marked as
   //    Dirichlet in order to enforce zero boundary conditions.
   Array<int> boundary_dofs;
   fespace.GetBoundaryTrueDofs(boundary_dofs);

   // 5. Define the solution x as a finite element grid function in fespace. Set
   //    the initial guess to zero, which also sets the boundary conditions.
   GridFunction x(&fespace);
   x = 0.0;

   // 6. Set up the linear form b(.) corresponding to the right-hand side.
   ConstantCoefficient one(1.0);
   LinearForm b(&fespace);
   b.AddDomainIntegrator(new DomainLFIntegrator(one));
   b.Assemble();

   // 7. Set up the bilinear form a(.,.) corresponding to the -Delta operator.
   BilinearForm a(&fespace);
   a.AddDomainIntegrator(new DiffusionIntegrator);
   a.Assemble();

   // 8. Form the linear system A X = B. This includes eliminating boundary
   //    conditions, applying AMR constraints, and other transformations.
   SparseMatrix A;
   Vector B, X;
   a.FormLinearSystem(boundary_dofs, x, b, A, X, B);

   // 9. Solve the system using PCG with symmetric Gauss-Seidel preconditioner.
   GSSmoother M(A);
   PCG(A, M, B, X, 1, 200, 1e-12, 0.0);

   // 10. Recover the solution x as a grid function and save to file. The output
   //     can be viewed using GLVis as follows: "glvis -m mesh.mesh -g sol.gf"
   a.RecoverFEMSolution(X, b, x);
   x.Save("sol.gf");
   mesh.Save("mesh.mesh")

   return 0;
}
<|endoftext|>


<commit_before>// To use this file, compile 'gcd.tmpc' with
// tmpcompiler -o gcd.hpp gcd.tmpc
#include <iostream>

#include "gcd.hpp"

template <typename T>
struct wrap
{
    typedef T type;
};

// Convert a template argument list (of ints) to a List as compiled by
// tmpcompiler.
template <int ... i>
struct ints_to_list;

template <>
struct ints_to_list<>
{
    typedef __data<0, __dummy> type;
};

template <int i, int ... j>
struct ints_to_list<i, j...>
{
    typedef __data<1, __dummy, Int<i>, typename ints_to_list<j...>::type> type;
};

int main()
{
    std::cout << "gcd(100, 80, 64) = "
        << gcds::type::apply<ints_to_list<100, 80, 64> >::type::value
        << "\n";
}
<commit_msg>Useless 'wrap'.<commit_after>// To use this file, compile 'gcd.tmpc' with
// tmpcompiler -o gcd.hpp gcd.tmpc
#include <iostream>

#include "gcd.hpp"

// Convert a template argument list (of ints) to a List as compiled by
// tmpcompiler.
template <int ... i>
struct ints_to_list;

template <>
struct ints_to_list<>
{
    typedef __data<0, __dummy> type;
};

template <int i, int ... j>
struct ints_to_list<i, j...>
{
    typedef __data<1, __dummy, Int<i>, typename ints_to_list<j...>::type> type;
};

int main()
{
    std::cout << "gcd(100, 80, 64) = "
        << gcds::type::apply<ints_to_list<100, 80, 64> >::type::value
        << "\n";
}
<|endoftext|>


<commit_before>/* $Id: $ */
/* $Log$ */

//------------------------------------
// Configuration macro example:
//
// Do prompt photon analysis with ESDs
// Gamma in PHOS,
// for EMCAL, PHOS by EMCAL where necessary
//
// Author : Gustavo Conesa Balbastre (INFN-LNF)
//------------------------------------

AliAnaMaker*  ConfigAnalysis()
{
  //
  // Configuration goes here
  //
  printf("======================== \n");
  printf("ConfigAnalysis() \n");
  printf("======================== \n");

  //Detector Fidutial Cuts
  AliFidutialCut * fidCut = new AliFidutialCut();
  fidCut->DoCTSFidutialCut(kTRUE) ;
  //fidCut->DoEMCALFidutialCut(kFALSE) ;
  fidCut->DoPHOSFidutialCut(kTRUE) ;

  fidCut->SetSimpleCTSFidutialCut(0.9,0.,360.);
  f//idCut->SetSimpleEMCALFidutialCut(0.7,80.,190.);
  fidCut->SetSimplePHOSFidutialCut(0.13,220.,320.);

  fidCut->Print("");

  //-----------------------------------------------------------
  // Reader
  //-----------------------------------------------------------
  AliCaloTrackReader *reader = new AliCaloTrackESDReader();
  reader->SetDebug(-1);

  //Switch on or off the detectors information that you want
  reader->SwitchOffEMCAL();
  reader->SwitchOnCTS();
  reader->SwitchOnPHOS();

  //Min particle pT
  //reader->SetEMCALPtMin(0.5);
  reader->SetPHOSPtMin(0.5);
  reader->SetCTSPtMin(0.2);

  reader->SetFidutialCut(fidCut);
  reader->Print("");

  //---------------------------------------------------------------------
  // Analysis algorithm
  //---------------------------------------------------------------------

  //Detector Fidutial Cuts for analysis part
  AliFidutialCut * fidCut2 = new AliFidutialCut();
  fidCut2->DoCTSFidutialCut(kFALSE) ;
  //fidCut2->DoEMCALFidutialCut(kTRUE) ;
  fidCut2->DoPHOSFidutialCut(kFALSE) ;

  fidCut2->SetSimpleCTSFidutialCut(0.9,0.,360.);
  //fidCut2->SetSimpleEMCALFidutialCut(0.7,80.,190.);
  fidCut2->SetSimplePHOSFidutialCut(0.13,220.,320.);
  fidCut2->Print("");

  AliCaloPID * pid = new AliCaloPID();
  // use selection with simple weights
  pid->SetPHOSPhotonWeight(0.7);    pid->SetPHOSPi0Weight(0.7);
  pid->SetEMCALPhotonWeight(0.7);    pid->SetEMCALPi0Weight(0.7);
  // use more complicated selection, particle weight depending on cluster energy
//   pid->UsePHOSPIDWeightFormula(kTRUE);
//   TFormula * photonF = new TFormula("photonWeight","0.98*(x<40)+ 0.68*(x>=100)+(x>=40 && x<100)*(0.98+x*(6e-3)-x*x*(2e-04)+x*x*x*(1.1e-06))");
//   TFormula * pi0F = new TFormula("pi0Weight","0.98*(x<65)+ 0.915*(x>=100)+(x>=65 && x-x*(1.95e-3)-x*x*(4.31e-05)+x*x*x*(3.61e-07))");
//   pid->SetPHOSPhotonWeightFormula(photonF);
//   pid->SetPHOSPi0WeightFormula(pi0F);
  pid->Print("");

  AliIsolationCut * ic = new AliIsolationCut();
  ic->SetConeSize(0.4);
  ic->SetPtThreshold(1.);
  ic->SetICMethod(AliIsolationCut::kPtThresIC);
  ic->Print("");

  AliAnaGammaDirect *ana = new AliAnaGammaDirect();
  ana->SetDebug(-1);
  ana->SetMinPt(5.);
  ana->SetCaloPID(pid);
  ana->SetFidutialCut(fidCut2);
  ana->SetIsolationCut(ic) ;
  ana->SetDetector("PHOS");
  ana->SwitchOnDataMC() ;//Access MC stack and fill more histograms

  ana->SwitchOnCaloPID();
  ana->SwitchOffCaloPIDRecalculation(); //recommended for EMCAL
  ana->SwitchOnFidutialCut();
  //Select clusters with no pair, if both clusters with pi0 mass
  ana->SwitchOffInvariantMass();
  //Do isolation cut
  ana->SwitchOnIsolation();

  //Do or not do isolation with previously produced AODs.
  //No effect if use of SwitchOnSeveralIsolation()
  ana->SwitchOffReIsolation();

  //Multiple IC
  ana->SwitchOffSeveralIsolation() ;
//   ana->SwitchOnSeveralIsolation() ;
//   ana->SetNCones(2) ;
//   ana->SetNPtThresFrac(2) ;
//   ana->SetConeSizes(0, 0.3) ; ana->SetConeSizes(1, 0.4) ;
//   ana->SetPtThresholds(0, 0.5) ;     ana->SetPtThresholds(1, 1.) ;
//   ana->SetPtFractions(0, 1.) ;   ana->SetPtFractions(1, 1.5) ;

  ana->Print("");

  //---------------------------------------------------------------------
  // Set  analysis algorithm and reader
  //---------------------------------------------------------------------
  maker = new AliAnaMaker();
  maker->SetReader(reader);//pointer to reader
  maker->AddAnalysis(ana,0);
  maker->SetAODBranchName("Photon");
  maker->SetAnaDebug(1)  ;
  maker->SwitchOnHistogramsMaker()  ;
  //maker->SwitchOffHistogramsMaker() ;
  maker->SwitchOnAODsMaker()  ;
  //maker->SwitchOffAODsMaker() ;

  maker->Print("");
  //
  printf("======================== \n");
  printf("END ConfigAnalysis() \n");
  printf("======================== \n");
  return maker ;
}
<commit_msg>correct typo<commit_after>/* $Id:$ */

//------------------------------------
// Configuration macro example:
//
// Do prompt photon analysis with ESDs
// Gamma in PHOS,
// for EMCAL, PHOS by EMCAL where necessary
//
// Author : Gustavo Conesa Balbastre (INFN-LNF)
//------------------------------------

AliAnaMaker*  ConfigAnalysis()
{
  //
  // Configuration goes here
  //
  printf("======================== \n");
  printf("ConfigAnalysis() \n");
  printf("======================== \n");

  //Detector Fidutial Cuts
  AliFidutialCut * fidCut = new AliFidutialCut();
  fidCut->DoCTSFidutialCut(kTRUE) ;
  //fidCut->DoEMCALFidutialCut(kFALSE) ;
  fidCut->DoPHOSFidutialCut(kTRUE) ;

  fidCut->SetSimpleCTSFidutialCut(0.9,0.,360.);
  //fidCut->SetSimpleEMCALFidutialCut(0.7,80.,190.);
  fidCut->SetSimplePHOSFidutialCut(0.13,220.,320.);

  fidCut->Print("");

  //-----------------------------------------------------------
  // Reader
  //-----------------------------------------------------------
  AliCaloTrackReader *reader = new AliCaloTrackESDReader();
  reader->SetDebug(-1);

  //Switch on or off the detectors information that you want
  reader->SwitchOffEMCAL();
  reader->SwitchOnCTS();
  reader->SwitchOnPHOS();

  //Min particle pT
  //reader->SetEMCALPtMin(0.5);
  reader->SetPHOSPtMin(0.5);
  reader->SetCTSPtMin(0.2);

  reader->SetFidutialCut(fidCut);
  reader->Print("");

  //---------------------------------------------------------------------
  // Analysis algorithm
  //---------------------------------------------------------------------

  //Detector Fidutial Cuts for analysis part
  AliFidutialCut * fidCut2 = new AliFidutialCut();
  fidCut2->DoCTSFidutialCut(kFALSE) ;
  //fidCut2->DoEMCALFidutialCut(kTRUE) ;
  fidCut2->DoPHOSFidutialCut(kFALSE) ;

  fidCut2->SetSimpleCTSFidutialCut(0.9,0.,360.);
  //fidCut2->SetSimpleEMCALFidutialCut(0.7,80.,190.);
  fidCut2->SetSimplePHOSFidutialCut(0.13,220.,320.);
  fidCut2->Print("");

  AliCaloPID * pid = new AliCaloPID();
  // use selection with simple weights
  pid->SetPHOSPhotonWeight(0.7);    pid->SetPHOSPi0Weight(0.7);
  pid->SetEMCALPhotonWeight(0.7);    pid->SetEMCALPi0Weight(0.7);
  // use more complicated selection, particle weight depending on cluster energy
//   pid->UsePHOSPIDWeightFormula(kTRUE);
//   TFormula * photonF = new TFormula("photonWeight","0.98*(x<40)+ 0.68*(x>=100)+(x>=40 && x<100)*(0.98+x*(6e-3)-x*x*(2e-04)+x*x*x*(1.1e-06))");
//   TFormula * pi0F = new TFormula("pi0Weight","0.98*(x<65)+ 0.915*(x>=100)+(x>=65 && x-x*(1.95e-3)-x*x*(4.31e-05)+x*x*x*(3.61e-07))");
//   pid->SetPHOSPhotonWeightFormula(photonF);
//   pid->SetPHOSPi0WeightFormula(pi0F);
  pid->Print("");

  AliIsolationCut * ic = new AliIsolationCut();
  ic->SetConeSize(0.4);
  ic->SetPtThreshold(1.);
  ic->SetICMethod(AliIsolationCut::kPtThresIC);
  ic->Print("");

  AliAnaGammaDirect *ana = new AliAnaGammaDirect();
  ana->SetDebug(-1);
  ana->SetMinPt(5.);
  ana->SetCaloPID(pid);
  ana->SetFidutialCut(fidCut2);
  ana->SetIsolationCut(ic) ;
  ana->SetDetector("PHOS");
  ana->SwitchOnDataMC() ;//Access MC stack and fill more histograms

  ana->SwitchOnCaloPID();
  ana->SwitchOffCaloPIDRecalculation(); //recommended for EMCAL
  ana->SwitchOnFidutialCut();
  //Select clusters with no pair, if both clusters with pi0 mass
  ana->SwitchOffInvariantMass();
  //Do isolation cut
  ana->SwitchOnIsolation();

  //Do or not do isolation with previously produced AODs.
  //No effect if use of SwitchOnSeveralIsolation()
  ana->SwitchOffReIsolation();

  //Multiple IC
  ana->SwitchOffSeveralIsolation() ;
//   ana->SwitchOnSeveralIsolation() ;
//   ana->SetNCones(2) ;
//   ana->SetNPtThresFrac(2) ;
//   ana->SetConeSizes(0, 0.3) ; ana->SetConeSizes(1, 0.4) ;
//   ana->SetPtThresholds(0, 0.5) ;     ana->SetPtThresholds(1, 1.) ;
//   ana->SetPtFractions(0, 1.) ;   ana->SetPtFractions(1, 1.5) ;

  ana->Print("");

  //---------------------------------------------------------------------
  // Set  analysis algorithm and reader
  //---------------------------------------------------------------------
  maker = new AliAnaMaker();
  maker->SetReader(reader);//pointer to reader
  maker->AddAnalysis(ana,0);
  maker->SetAODBranchName("Photon");
  maker->SetAnaDebug(1)  ;
  maker->SwitchOnHistogramsMaker()  ;
  //maker->SwitchOffHistogramsMaker() ;
  maker->SwitchOnAODsMaker()  ;
  //maker->SwitchOffAODsMaker() ;

  maker->Print("");
  //
  printf("======================== \n");
  printf("END ConfigAnalysis() \n");
  printf("======================== \n");
  return maker ;
}
<|endoftext|>