FX_BOOL CFX_ImageTransformer::Start() {
  CFX_FloatRect unit_rect = m_pMatrix->GetUnitRect();
  FX_RECT result_rect = unit_rect.GetClosestRect();
  FX_RECT result_clip = result_rect;
  if (m_pClip)
    result_clip.Intersect(*m_pClip);

  if (result_clip.IsEmpty())
    return FALSE;

  m_result = result_clip;
  if (FXSYS_fabs(m_pMatrix->a) < FXSYS_fabs(m_pMatrix->b) / 20 &&
      FXSYS_fabs(m_pMatrix->d) < FXSYS_fabs(m_pMatrix->c) / 20 &&
      FXSYS_fabs(m_pMatrix->a) < 0.5f && FXSYS_fabs(m_pMatrix->d) < 0.5f) {
    int dest_width = result_rect.Width();
    int dest_height = result_rect.Height();
    result_clip.Offset(-result_rect.left, -result_rect.top);
    result_clip = FXDIB_SwapClipBox(result_clip, dest_width, dest_height,
                                    m_pMatrix->c > 0, m_pMatrix->b < 0);
    m_Stretcher = WrapUnique(new CFX_ImageStretcher(
        &m_Storer, m_pSrc, dest_height, dest_width, result_clip, m_Flags));
    m_Stretcher->Start();
    m_Status = 1;
    return TRUE;
  }
  if (FXSYS_fabs(m_pMatrix->b) < FIX16_005 &&
      FXSYS_fabs(m_pMatrix->c) < FIX16_005) {
    int dest_width = m_pMatrix->a > 0 ? (int)FXSYS_ceil(m_pMatrix->a)
                                      : (int)FXSYS_floor(m_pMatrix->a);
    int dest_height = m_pMatrix->d > 0 ? (int)-FXSYS_ceil(m_pMatrix->d)
                                       : (int)-FXSYS_floor(m_pMatrix->d);
    result_clip.Offset(-result_rect.left, -result_rect.top);
    m_Stretcher = WrapUnique(new CFX_ImageStretcher(
        &m_Storer, m_pSrc, dest_width, dest_height, result_clip, m_Flags));
    m_Stretcher->Start();
    m_Status = 2;
    return TRUE;
  }
  int stretch_width = (int)FXSYS_ceil(FXSYS_sqrt2(m_pMatrix->a, m_pMatrix->b));
  int stretch_height = (int)FXSYS_ceil(FXSYS_sqrt2(m_pMatrix->c, m_pMatrix->d));
  CFX_Matrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
                          (FX_FLOAT)(stretch_height));
  stretch2dest.Concat(
      m_pMatrix->a / stretch_width, m_pMatrix->b / stretch_width,
      m_pMatrix->c / stretch_height, m_pMatrix->d / stretch_height,
      m_pMatrix->e, m_pMatrix->f);
  m_dest2stretch.SetReverse(stretch2dest);
  CFX_FloatRect clip_rect_f(result_clip);
  clip_rect_f.Transform(&m_dest2stretch);
  m_StretchClip = clip_rect_f.GetOuterRect();
  m_StretchClip.Intersect(0, 0, stretch_width, stretch_height);
  m_Stretcher = WrapUnique(new CFX_ImageStretcher(&m_Storer, m_pSrc,
                                                  stretch_width, stretch_height,
                                                  m_StretchClip, m_Flags));
  m_Stretcher->Start();
  m_Status = 3;
  return TRUE;
}
FX_BOOL CFX_ImageTransformer::Start(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix, int flags, const FX_RECT* pDestClip)
{
    m_pMatrix = (CFX_AffineMatrix*)pDestMatrix;
    CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect();
    FX_RECT result_rect = unit_rect.GetClosestRect();
    FX_RECT result_clip = result_rect;
    if (pDestClip) {
        result_clip.Intersect(*pDestClip);
    }
    if (result_clip.IsEmpty()) {
        return FALSE;
    }
    m_ResultLeft = result_clip.left;
    m_ResultTop = result_clip.top;
    m_ResultWidth = result_clip.Width();
    m_ResultHeight = result_clip.Height();
    m_Flags = flags;
    if (FXSYS_fabs(pDestMatrix->a) < FXSYS_fabs(pDestMatrix->b) / 20 &&
            FXSYS_fabs(pDestMatrix->d) < FXSYS_fabs(pDestMatrix->c) / 20 &&
            FXSYS_fabs(pDestMatrix->a) < 0.5f && FXSYS_fabs(pDestMatrix->d) < 0.5f) {
        int dest_width = result_rect.Width();
        int dest_height = result_rect.Height();
        result_clip.Offset(-result_rect.left, -result_rect.top);
        result_clip = _FXDIB_SwapClipBox(result_clip, dest_width, dest_height, pDestMatrix->c > 0, pDestMatrix->b < 0);
        m_Stretcher.Start(&m_Storer, pSrc, dest_height, dest_width, result_clip, flags);
        m_Status = 1;
        return TRUE;
    }
    if (FXSYS_fabs(pDestMatrix->b) < FIX16_005 && FXSYS_fabs(pDestMatrix->c) < FIX16_005) {
        int dest_width = pDestMatrix->a > 0 ? (int)FXSYS_ceil(pDestMatrix->a) : (int)FXSYS_floor(pDestMatrix->a);
        int dest_height = pDestMatrix->d > 0 ? (int) - FXSYS_ceil(pDestMatrix->d) : (int) - FXSYS_floor(pDestMatrix->d);
        result_clip.Offset(-result_rect.left, -result_rect.top);
        m_Stretcher.Start(&m_Storer, pSrc, dest_width, dest_height, result_clip, flags);
        m_Status = 2;
        return TRUE;
    }
    int stretch_width = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->a, pDestMatrix->b));
    int stretch_height = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->c, pDestMatrix->d));
    CFX_AffineMatrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, (FX_FLOAT)(stretch_height));
    stretch2dest.Concat(pDestMatrix->a / stretch_width, pDestMatrix->b / stretch_width,
                        pDestMatrix->c / stretch_height, pDestMatrix->d / stretch_height, pDestMatrix->e, pDestMatrix->f);
    m_dest2stretch.SetReverse(stretch2dest);
    CFX_FloatRect clip_rect_f(result_clip);
    clip_rect_f.Transform(&m_dest2stretch);
    m_StretchClip = clip_rect_f.GetOutterRect();
    m_StretchClip.Intersect(0, 0, stretch_width, stretch_height);
    m_Stretcher.Start(&m_Storer, pSrc, stretch_width, stretch_height, m_StretchClip, flags);
    m_Status = 3;
    return TRUE;
}
Exemple #3
0
static void _UpdateLineEndPoints(CFX_FloatRect& rect,
                                 FX_FLOAT start_x,
                                 FX_FLOAT start_y,
                                 FX_FLOAT end_x,
                                 FX_FLOAT end_y,
                                 FX_FLOAT hw) {
  if (start_x == end_x) {
    if (start_y == end_y) {
      rect.UpdateRect(end_x + hw, end_y + hw);
      rect.UpdateRect(end_x - hw, end_y - hw);
      return;
    }
    FX_FLOAT point_y;
    if (end_y < start_y) {
      point_y = end_y - hw;
    } else {
      point_y = end_y + hw;
    }
    rect.UpdateRect(end_x + hw, point_y);
    rect.UpdateRect(end_x - hw, point_y);
    return;
  }
  if (start_y == end_y) {
    FX_FLOAT point_x;
    if (end_x < start_x) {
      point_x = end_x - hw;
    } else {
      point_x = end_x + hw;
    }
    rect.UpdateRect(point_x, end_y + hw);
    rect.UpdateRect(point_x, end_y - hw);
    return;
  }
  FX_FLOAT dx = end_x - start_x;
  FX_FLOAT dy = end_y - start_y;
  FX_FLOAT ll = FXSYS_sqrt2(dx, dy);
  FX_FLOAT mx = end_x + hw * dx / ll;
  FX_FLOAT my = end_y + hw * dy / ll;
  FX_FLOAT dx1 = hw * dy / ll;
  FX_FLOAT dy1 = hw * dx / ll;
  rect.UpdateRect(mx - dx1, my + dy1);
  rect.UpdateRect(mx + dx1, my - dy1);
}
Exemple #4
0
static void _UpdateLineJoinPoints(CFX_FloatRect& rect,
                                  FX_FLOAT start_x,
                                  FX_FLOAT start_y,
                                  FX_FLOAT middle_x,
                                  FX_FLOAT middle_y,
                                  FX_FLOAT end_x,
                                  FX_FLOAT end_y,
                                  FX_FLOAT half_width,
                                  FX_FLOAT miter_limit) {
  FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0,
           start_dc = 0, end_len = 0, end_dc = 0;
  FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20;
  FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20;
  if (bStartVert && bEndVert) {
    int start_dir = middle_y > start_y ? 1 : -1;
    FX_FLOAT point_y = middle_y + half_width * start_dir;
    rect.UpdateRect(middle_x + half_width, point_y);
    rect.UpdateRect(middle_x - half_width, point_y);
    return;
  }
  if (!bStartVert) {
    start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x);
    start_c = middle_y - FXSYS_Mul(start_k, middle_x);
    start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y);
    start_dc = (FX_FLOAT)FXSYS_fabs(
        FXSYS_MulDiv(half_width, start_len, start_x - middle_x));
  }
  if (!bEndVert) {
    end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x);
    end_c = middle_y - FXSYS_Mul(end_k, middle_x);
    end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y);
    end_dc = (FX_FLOAT)FXSYS_fabs(
        FXSYS_MulDiv(half_width, end_len, end_x - middle_x));
  }
  if (bStartVert) {
    FX_FLOAT outside_x = start_x;
    if (end_x < start_x) {
      outside_x += half_width;
    } else {
      outside_x -= half_width;
    }
    FX_FLOAT outside_y;
    if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
      outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc;
    } else {
      outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc;
    }
    rect.UpdateRect(outside_x, outside_y);
    return;
  }
  if (bEndVert) {
    FX_FLOAT outside_x = end_x;
    if (start_x < end_x) {
      outside_x += half_width;
    } else {
      outside_x -= half_width;
    }
    FX_FLOAT outside_y;
    if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
      outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc;
    } else {
      outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc;
    }
    rect.UpdateRect(outside_x, outside_y);
    return;
  }
  if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) {
    int start_dir = middle_x > start_x ? 1 : -1;
    int end_dir = end_x > middle_x ? 1 : -1;
    if (start_dir == end_dir) {
      _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width);
    } else {
      _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y,
                           half_width);
    }
    return;
  }
  FX_FLOAT start_outside_c = start_c;
  if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
    start_outside_c += start_dc;
  } else {
    start_outside_c -= start_dc;
  }
  FX_FLOAT end_outside_c = end_c;
  if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
    end_outside_c += end_dc;
  } else {
    end_outside_c -= end_dc;
  }
  FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k);
  FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c;
  rect.UpdateRect(join_x, join_y);
}