示例#1
0
void CWeightTable::Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, int flags)
{
    if (m_pWeightTables) {
        FX_Free(m_pWeightTables);
        m_pWeightTables = NULL;
    }
    double scale, base;
    scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len));
    if (dest_len < 0) {
        base = (FX_FLOAT)(src_len);
    } else {
        base = 0;
    }
    int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1;
    m_ItemSize = sizeof(int) * 2 + (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size));
    m_DestMin = dest_min;
    if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) {
        return;
    }
    m_pWeightTables = FX_TryAlloc(FX_BYTE, (dest_max - dest_min) * m_ItemSize + 4);
    if (m_pWeightTables == NULL) {
        return;
    }
    if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) {
        for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {
            PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
            double src_pos = dest_pixel * scale + scale / 2 + base;
            if (flags & FXDIB_INTERPOL) {
                pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2);
                pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2);
                if (pixel_weights.m_SrcStart < src_min) {
                    pixel_weights.m_SrcStart = src_min;
                }
                if (pixel_weights.m_SrcEnd >= src_max) {
                    pixel_weights.m_SrcEnd = src_max - 1;
                }
                if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
                    pixel_weights.m_Weights[0] = 65536;
                } else {
                    pixel_weights.m_Weights[1] = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 65536);
                    pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1];
                }
            } else if (flags & FXDIB_BICUBIC_INTERPOL) {
                pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2);
                pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2);
                int start = pixel_weights.m_SrcStart - 1;
                int end = pixel_weights.m_SrcEnd + 1;
                if (start < src_min) {
                    start = src_min;
                }
                if (end >= src_max) {
                    end = src_max - 1;
                }
                if (pixel_weights.m_SrcStart < src_min) {
                    src_pos += src_min - pixel_weights.m_SrcStart;
                    pixel_weights.m_SrcStart = src_min;
                }
                if (pixel_weights.m_SrcEnd >= src_max) {
                    pixel_weights.m_SrcEnd = src_max - 1;
                }
                int weight;
                weight = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 256);
                if (start == end) {
                    pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
                } else if ((start == pixel_weights.m_SrcStart && (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd ||
                            end == pixel_weights.m_SrcEnd) && start < end) || (start < pixel_weights.m_SrcStart && pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd && end == pixel_weights.m_SrcEnd)) {
                    if (start < pixel_weights.m_SrcStart) {
                        pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8;
                        pixel_weights.m_Weights[1] = (SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
                    } else {
                        if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
                            pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight]) << 8;
                            pixel_weights.m_Weights[1] = SDP_Table[512 - weight] << 8;
                        } else {
                            pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8;
                            pixel_weights.m_Weights[1] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
                        }
                    }
                    if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
                        pixel_weights.m_SrcEnd = end;
                    }
                    if (start < pixel_weights.m_SrcStart) {
                        pixel_weights.m_SrcStart = start;
                    }
                } else if (start == pixel_weights.m_SrcStart &&
                           start < pixel_weights.m_SrcEnd &&
                           pixel_weights.m_SrcEnd < end) {
                    pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8;
                    pixel_weights.m_Weights[1] = SDP_Table[256 - weight] << 8;
                    pixel_weights.m_Weights[2] = SDP_Table[512 - weight] << 8;
                    pixel_weights.m_SrcEnd = end;
                } else if (start < pixel_weights.m_SrcStart &&
                           pixel_weights.m_SrcStart < pixel_weights.m_SrcEnd &&
                           pixel_weights.m_SrcEnd == end) {
                    pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8;
                    pixel_weights.m_Weights[1] = SDP_Table[weight] << 8;
                    pixel_weights.m_Weights[2] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
                    pixel_weights.m_SrcStart = start;
                } else {
                    pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8;
                    pixel_weights.m_Weights[1] = SDP_Table[weight] << 8;
                    pixel_weights.m_Weights[2] = SDP_Table[256 - weight] << 8;
                    pixel_weights.m_Weights[3] = SDP_Table[512 - weight] << 8;
                    pixel_weights.m_SrcStart = start;
                    pixel_weights.m_SrcEnd = end;
                }
            } else {
                pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos);
                if (pixel_weights.m_SrcStart < src_min) {
                    pixel_weights.m_SrcStart = src_min;
                }
                if (pixel_weights.m_SrcEnd >= src_max) {
                    pixel_weights.m_SrcEnd = src_max - 1;
                }
                pixel_weights.m_Weights[0] = 65536;
            }
        }
        return;
    }
    for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {
        PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
        double src_start = dest_pixel * scale + base;
        double src_end = src_start + scale;
        int start_i, end_i;
        if (src_start < src_end) {
            start_i = (int)FXSYS_floor((FX_FLOAT)src_start);
            end_i = (int)FXSYS_ceil((FX_FLOAT)src_end);
        } else {
            start_i = (int)FXSYS_floor((FX_FLOAT)src_end);
            end_i = (int)FXSYS_ceil((FX_FLOAT)src_start);
        }
        if (start_i < src_min) {
            start_i = src_min;
        }
        if (end_i >= src_max) {
            end_i = src_max - 1;
        }
        if (start_i > end_i) {
            if (start_i >= src_max) {
                start_i = src_max - 1;
            }
            pixel_weights.m_SrcStart = start_i;
            pixel_weights.m_SrcEnd = start_i;
            continue;
        }
        pixel_weights.m_SrcStart = start_i;
        pixel_weights.m_SrcEnd = end_i;
        for (int j = start_i; j <= end_i; j ++) {
            double dest_start = FXSYS_Div((FX_FLOAT)(j) - base, scale);
            double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale);
            if (dest_start > dest_end) {
                double temp = dest_start;
                dest_start = dest_end;
                dest_end = temp;
            }
            double area_start = dest_start > (FX_FLOAT)(dest_pixel) ? dest_start : (FX_FLOAT)(dest_pixel);
            double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) ? (FX_FLOAT)(dest_pixel + 1) : dest_end;
            double weight = area_start >= area_end ? 0.0f : area_end - area_start;
            if (weight == 0 && j == end_i) {
                pixel_weights.m_SrcEnd --;
                break;
            }
            pixel_weights.m_Weights[j - start_i] = FXSYS_round((FX_FLOAT)(weight * 65536));
        }
    }
}
示例#2
0
CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap,
                               FXDIB_Format dest_format,
                               int dest_width,
                               int dest_height,
                               const FX_RECT& clip_rect,
                               const CFX_DIBSource* pSrcBitmap,
                               int flags) {
  m_State = 0;
  m_DestFormat = dest_format;
  m_DestBpp = dest_format & 0xff;
  m_SrcBpp = pSrcBitmap->GetFormat() & 0xff;
  m_bHasAlpha = pSrcBitmap->GetFormat() & 0x200;
  m_pSrcPalette = pSrcBitmap->GetPalette();
  m_pDestBitmap = pDestBitmap;
  m_DestWidth = dest_width;
  m_DestHeight = dest_height;
  m_pInterBuf = nullptr;
  m_pExtraAlphaBuf = nullptr;
  m_pDestMaskScanline = nullptr;
  m_DestClip = clip_rect;
  uint32_t size = clip_rect.Width();
  if (size && m_DestBpp > (int)(INT_MAX / size)) {
    return;
  }
  size *= m_DestBpp;
  if (size > INT_MAX - 31) {
    return;
  }
  size += 31;
  size = size / 32 * 4;
  m_pDestScanline = FX_TryAlloc(uint8_t, size);
  if (!m_pDestScanline) {
    return;
  }
  if (dest_format == FXDIB_Rgb32) {
    FXSYS_memset(m_pDestScanline, 255, size);
  }
  m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4;
  m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4;
  m_pInterBuf = nullptr;
  m_pSource = pSrcBitmap;
  m_SrcWidth = pSrcBitmap->GetWidth();
  m_SrcHeight = pSrcBitmap->GetHeight();
  m_SrcPitch = (m_SrcWidth * m_SrcBpp + 31) / 32 * 4;
  if ((flags & FXDIB_NOSMOOTH) == 0) {
    bool bInterpol = flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL;
    if (!bInterpol && FXSYS_abs(dest_width) != 0 &&
        FXSYS_abs(dest_height) / 8 < static_cast<long long>(m_SrcWidth) *
                                         m_SrcHeight / FXSYS_abs(dest_width)) {
      flags = FXDIB_INTERPOL;
    }
    m_Flags = flags;
  } else {
    m_Flags = FXDIB_NOSMOOTH;
    if (flags & FXDIB_DOWNSAMPLE) {
      m_Flags |= FXDIB_DOWNSAMPLE;
    }
  }
  double scale_x = (FX_FLOAT)m_SrcWidth / (FX_FLOAT)m_DestWidth;
  double scale_y = (FX_FLOAT)m_SrcHeight / (FX_FLOAT)m_DestHeight;
  double base_x = m_DestWidth > 0 ? 0.0f : (FX_FLOAT)(m_DestWidth);
  double base_y = m_DestHeight > 0 ? 0.0f : (FX_FLOAT)(m_DestHeight);
  double src_left = scale_x * ((FX_FLOAT)(clip_rect.left) + base_x);
  double src_right = scale_x * ((FX_FLOAT)(clip_rect.right) + base_x);
  double src_top = scale_y * ((FX_FLOAT)(clip_rect.top) + base_y);
  double src_bottom = scale_y * ((FX_FLOAT)(clip_rect.bottom) + base_y);
  if (src_left > src_right) {
    double temp = src_left;
    src_left = src_right;
    src_right = temp;
  }
  if (src_top > src_bottom) {
    double temp = src_top;
    src_top = src_bottom;
    src_bottom = temp;
  }
  m_SrcClip.left = (int)FXSYS_floor((FX_FLOAT)src_left);
  m_SrcClip.right = (int)FXSYS_ceil((FX_FLOAT)src_right);
  m_SrcClip.top = (int)FXSYS_floor((FX_FLOAT)src_top);
  m_SrcClip.bottom = (int)FXSYS_ceil((FX_FLOAT)src_bottom);
  FX_RECT src_rect(0, 0, m_SrcWidth, m_SrcHeight);
  m_SrcClip.Intersect(src_rect);
  if (m_SrcBpp == 1) {
    if (m_DestBpp == 8) {
      m_TransMethod = 1;
    } else {
      m_TransMethod = 2;
    }
  } else if (m_SrcBpp == 8) {
    if (m_DestBpp == 8) {
      if (!m_bHasAlpha) {
        m_TransMethod = 3;
      } else {
        m_TransMethod = 4;
      }
    } else {
      if (!m_bHasAlpha) {
        m_TransMethod = 5;
      } else {
        m_TransMethod = 6;
      }
    }
  } else {
    if (!m_bHasAlpha) {
      m_TransMethod = 7;
    } else {
      m_TransMethod = 8;
    }
  }
}
示例#3
0
static void DrawGouraud(CFX_DIBitmap* pBitmap,
                        int alpha,
                        CPDF_MeshVertex triangle[3]) {
  FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y;
  for (int i = 1; i < 3; i++) {
    if (min_y > triangle[i].y) {
      min_y = triangle[i].y;
    }
    if (max_y < triangle[i].y) {
      max_y = triangle[i].y;
    }
  }
  if (min_y == max_y) {
    return;
  }
  int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y);
  if (min_yi < 0) {
    min_yi = 0;
  }
  if (max_yi >= pBitmap->GetHeight()) {
    max_yi = pBitmap->GetHeight() - 1;
  }
  for (int y = min_yi; y <= max_yi; y++) {
    int nIntersects = 0;
    FX_FLOAT inter_x[3], r[3], g[3], b[3];
    for (int i = 0; i < 3; i++) {
      CPDF_MeshVertex& vertex1 = triangle[i];
      CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3];
      FX_BOOL bIntersect = _GetScanlineIntersect(
          y, vertex1.x, vertex1.y, vertex2.x, vertex2.y, inter_x[nIntersects]);
      if (!bIntersect) {
        continue;
      }
      r[nIntersects] =
          vertex1.r + FXSYS_MulDiv(vertex2.r - vertex1.r, y - vertex1.y,
                                   vertex2.y - vertex1.y);
      g[nIntersects] =
          vertex1.g + FXSYS_MulDiv(vertex2.g - vertex1.g, y - vertex1.y,
                                   vertex2.y - vertex1.y);
      b[nIntersects] =
          vertex1.b + FXSYS_MulDiv(vertex2.b - vertex1.b, y - vertex1.y,
                                   vertex2.y - vertex1.y);
      nIntersects++;
    }
    if (nIntersects != 2) {
      continue;
    }
    int min_x, max_x, start_index, end_index;
    if (inter_x[0] < inter_x[1]) {
      min_x = (int)FXSYS_floor(inter_x[0]);
      max_x = (int)FXSYS_ceil(inter_x[1]);
      start_index = 0;
      end_index = 1;
    } else {
      min_x = (int)FXSYS_floor(inter_x[1]);
      max_x = (int)FXSYS_ceil(inter_x[0]);
      start_index = 1;
      end_index = 0;
    }
    int start_x = min_x, end_x = max_x;
    if (start_x < 0) {
      start_x = 0;
    }
    if (end_x > pBitmap->GetWidth()) {
      end_x = pBitmap->GetWidth();
    }
    uint8_t* dib_buf =
        pBitmap->GetBuffer() + y * pBitmap->GetPitch() + start_x * 4;
    FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x);
    FX_FLOAT g_unit = (g[end_index] - g[start_index]) / (max_x - min_x);
    FX_FLOAT b_unit = (b[end_index] - b[start_index]) / (max_x - min_x);
    FX_FLOAT R = r[start_index] + (start_x - min_x) * r_unit;
    FX_FLOAT G = g[start_index] + (start_x - min_x) * g_unit;
    FX_FLOAT B = b[start_index] + (start_x - min_x) * b_unit;
    for (int x = start_x; x < end_x; x++) {
      R += r_unit;
      G += g_unit;
      B += b_unit;
      FXARGB_SETDIB(dib_buf,
                    FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255),
                                (int32_t)(B * 255)));
      dib_buf += 4;
    }
  }
}
示例#4
0
void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern,
                                          CPDF_PageObject* pPageObj,
                                          const CFX_AffineMatrix* pObj2Device,
                                          FX_BOOL bStroke) {
  if (!pPattern->Load()) {
    return;
  }
  m_pDevice->SaveState();
  if (pPageObj->m_Type == PDFPAGE_PATH) {
    if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) {
      m_pDevice->RestoreState();
      return;
    }
  } else if (pPageObj->m_Type == PDFPAGE_IMAGE) {
    FX_RECT rect = pPageObj->GetBBox(pObj2Device);
    m_pDevice->SetClip_Rect(&rect);
  } else {
    return;
  }
  FX_RECT clip_box = m_pDevice->GetClipBox();
  if (clip_box.IsEmpty()) {
    m_pDevice->RestoreState();
    return;
  }
  CFX_Matrix dCTM = m_pDevice->GetCTM();
  FX_FLOAT sa = FXSYS_fabs(dCTM.a);
  FX_FLOAT sd = FXSYS_fabs(dCTM.d);
  clip_box.right = clip_box.left + (int32_t)FXSYS_ceil(clip_box.Width() * sa);
  clip_box.bottom = clip_box.top + (int32_t)FXSYS_ceil(clip_box.Height() * sd);
  CFX_AffineMatrix mtPattern2Device = pPattern->m_Pattern2Form;
  mtPattern2Device.Concat(*pObj2Device);
  GetScaledMatrix(mtPattern2Device);
  FX_BOOL bAligned = FALSE;
  if (pPattern->m_BBox.left == 0 && pPattern->m_BBox.bottom == 0 &&
      pPattern->m_BBox.right == pPattern->m_XStep &&
      pPattern->m_BBox.top == pPattern->m_YStep &&
      (mtPattern2Device.IsScaled() || mtPattern2Device.Is90Rotated())) {
    bAligned = TRUE;
  }
  CFX_FloatRect cell_bbox = pPattern->m_BBox;
  mtPattern2Device.TransformRect(cell_bbox);
  int width = (int)FXSYS_ceil(cell_bbox.Width());
  int height = (int)FXSYS_ceil(cell_bbox.Height());
  if (width == 0) {
    width = 1;
  }
  if (height == 0) {
    height = 1;
  }
  int min_col, max_col, min_row, max_row;
  CFX_AffineMatrix mtDevice2Pattern;
  mtDevice2Pattern.SetReverse(mtPattern2Device);
  CFX_FloatRect clip_box_p(clip_box);
  clip_box_p.Transform(&mtDevice2Pattern);
  min_col = (int)FXSYS_ceil(
      FXSYS_Div(clip_box_p.left - pPattern->m_BBox.right, pPattern->m_XStep));
  max_col = (int)FXSYS_floor(
      FXSYS_Div(clip_box_p.right - pPattern->m_BBox.left, pPattern->m_XStep));
  min_row = (int)FXSYS_ceil(
      FXSYS_Div(clip_box_p.bottom - pPattern->m_BBox.top, pPattern->m_YStep));
  max_row = (int)FXSYS_floor(
      FXSYS_Div(clip_box_p.top - pPattern->m_BBox.bottom, pPattern->m_YStep));
  if (width > clip_box.Width() || height > clip_box.Height() ||
      width * height > clip_box.Width() * clip_box.Height()) {
    CPDF_GraphicStates* pStates = NULL;
    if (!pPattern->m_bColored) {
      pStates = CloneObjStates(pPageObj, bStroke);
    }
    CPDF_Dictionary* pFormResource = NULL;
    if (pPattern->m_pForm->m_pFormDict) {
      pFormResource =
          pPattern->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
    }
    for (int col = min_col; col <= max_col; col++)
      for (int row = min_row; row <= max_row; row++) {
        FX_FLOAT orig_x, orig_y;
        orig_x = col * pPattern->m_XStep;
        orig_y = row * pPattern->m_YStep;
        mtPattern2Device.Transform(orig_x, orig_y);
        CFX_AffineMatrix matrix = *pObj2Device;
        matrix.Translate(orig_x - mtPattern2Device.e,
                         orig_y - mtPattern2Device.f);
        m_pDevice->SaveState();
        CPDF_RenderStatus status;
        status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates,
                          &m_Options, pPattern->m_pForm->m_Transparency,
                          m_bDropObjects, pFormResource);
        status.RenderObjectList(pPattern->m_pForm, &matrix);
        m_pDevice->RestoreState();
      }
    m_pDevice->RestoreState();
    delete pStates;
    return;
  }
  if (bAligned) {
    int orig_x = FXSYS_round(mtPattern2Device.e);
    int orig_y = FXSYS_round(mtPattern2Device.f);
    min_col = (clip_box.left - orig_x) / width;
    if (clip_box.left < orig_x) {
      min_col--;
    }
    max_col = (clip_box.right - orig_x) / width;
    if (clip_box.right <= orig_x) {
      max_col--;
    }
    min_row = (clip_box.top - orig_y) / height;
    if (clip_box.top < orig_y) {
      min_row--;
    }
    max_row = (clip_box.bottom - orig_y) / height;
    if (clip_box.bottom <= orig_y) {
      max_row--;
    }
  }
  FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e;
  FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f;
  CFX_DIBitmap* pPatternBitmap = NULL;
  if (width * height < 16) {
    CFX_DIBitmap* pEnlargedBitmap =
        DrawPatternBitmap(m_pContext->m_pDocument, m_pContext->m_pPageCache,
                          pPattern, pObj2Device, 8, 8, m_Options.m_Flags);
    pPatternBitmap = pEnlargedBitmap->StretchTo(width, height);
    delete pEnlargedBitmap;
  } else {
    pPatternBitmap = DrawPatternBitmap(
        m_pContext->m_pDocument, m_pContext->m_pPageCache, pPattern,
        pObj2Device, width, height, m_Options.m_Flags);
  }
  if (pPatternBitmap == NULL) {
    m_pDevice->RestoreState();
    return;
  }
  if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
    pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor,
                                      m_Options.m_BackColor);
  }
  FX_ARGB fill_argb = GetFillArgb(pPageObj);
  int clip_width = clip_box.right - clip_box.left;
  int clip_height = clip_box.bottom - clip_box.top;
  CFX_DIBitmap screen;
  if (!screen.Create(clip_width, clip_height, FXDIB_Argb)) {
    return;
  }
  screen.Clear(0);
  FX_DWORD* src_buf = (FX_DWORD*)pPatternBitmap->GetBuffer();
  for (int col = min_col; col <= max_col; col++) {
    for (int row = min_row; row <= max_row; row++) {
      int start_x, start_y;
      if (bAligned) {
        start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_box.left;
        start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_box.top;
      } else {
        FX_FLOAT orig_x = col * pPattern->m_XStep;
        FX_FLOAT orig_y = row * pPattern->m_YStep;
        mtPattern2Device.Transform(orig_x, orig_y);
        start_x = FXSYS_round(orig_x + left_offset) - clip_box.left;
        start_y = FXSYS_round(orig_y + top_offset) - clip_box.top;
      }
      if (width == 1 && height == 1) {
        if (start_x < 0 || start_x >= clip_box.Width() || start_y < 0 ||
            start_y >= clip_box.Height()) {
          continue;
        }
        FX_DWORD* dest_buf =
            (FX_DWORD*)(screen.GetBuffer() + screen.GetPitch() * start_y +
                        start_x * 4);
        if (pPattern->m_bColored) {
          *dest_buf = *src_buf;
        } else {
          *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff);
        }
      } else {
        if (pPattern->m_bColored) {
          screen.CompositeBitmap(start_x, start_y, width, height,
                                 pPatternBitmap, 0, 0);
        } else {
          screen.CompositeMask(start_x, start_y, width, height, pPatternBitmap,
                               fill_argb, 0, 0);
        }
      }
    }
  }
  CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255,
                    FXDIB_BLEND_NORMAL, FALSE);
  m_pDevice->RestoreState();
  delete pPatternBitmap;
}
示例#5
0
FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op) {
  int i1, i2;
  FX_FLOAT d1, d2;
  switch (op) {
    case PSOP_ADD:
      d1 = Pop();
      d2 = Pop();
      Push(d1 + d2);
      break;
    case PSOP_SUB:
      d2 = Pop();
      d1 = Pop();
      Push(d1 - d2);
      break;
    case PSOP_MUL:
      d1 = Pop();
      d2 = Pop();
      Push(d1 * d2);
      break;
    case PSOP_DIV:
      d2 = Pop();
      d1 = Pop();
      Push(d1 / d2);
      break;
    case PSOP_IDIV:
      i2 = (int)Pop();
      i1 = (int)Pop();
      Push(i1 / i2);
      break;
    case PSOP_MOD:
      i2 = (int)Pop();
      i1 = (int)Pop();
      Push(i1 % i2);
      break;
    case PSOP_NEG:
      d1 = Pop();
      Push(-d1);
      break;
    case PSOP_ABS:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_fabs(d1));
      break;
    case PSOP_CEILING:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_ceil(d1));
      break;
    case PSOP_FLOOR:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_floor(d1));
      break;
    case PSOP_ROUND:
      d1 = Pop();
      Push(FXSYS_round(d1));
      break;
    case PSOP_TRUNCATE:
      i1 = (int)Pop();
      Push(i1);
      break;
    case PSOP_SQRT:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_sqrt(d1));
      break;
    case PSOP_SIN:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_sin(d1 * PI / 180.0f));
      break;
    case PSOP_COS:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_cos(d1 * PI / 180.0f));
      break;
    case PSOP_ATAN:
      d2 = Pop();
      d1 = Pop();
      d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / PI);
      if (d1 < 0) {
        d1 += 360;
      }
      Push(d1);
      break;
    case PSOP_EXP:
      d2 = Pop();
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_pow(d1, d2));
      break;
    case PSOP_LN:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_log(d1));
      break;
    case PSOP_LOG:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_log10(d1));
      break;
    case PSOP_CVI:
      i1 = (int)Pop();
      Push(i1);
      break;
    case PSOP_CVR:
      break;
    case PSOP_EQ:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 == d2));
      break;
    case PSOP_NE:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 != d2));
      break;
    case PSOP_GT:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 > d2));
      break;
    case PSOP_GE:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 >= d2));
      break;
    case PSOP_LT:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 < d2));
      break;
    case PSOP_LE:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 <= d2));
      break;
    case PSOP_AND:
      i1 = (int)Pop();
      i2 = (int)Pop();
      Push(i1 & i2);
      break;
    case PSOP_OR:
      i1 = (int)Pop();
      i2 = (int)Pop();
      Push(i1 | i2);
      break;
    case PSOP_XOR:
      i1 = (int)Pop();
      i2 = (int)Pop();
      Push(i1 ^ i2);
      break;
    case PSOP_NOT:
      i1 = (int)Pop();
      Push((int)!i1);
      break;
    case PSOP_BITSHIFT: {
      int shift = (int)Pop();
      int i = (int)Pop();
      if (shift > 0) {
        Push(i << shift);
      } else {
        Push(i >> -shift);
      }
      break;
    }
    case PSOP_TRUE:
      Push(1);
      break;
    case PSOP_FALSE:
      Push(0);
      break;
    case PSOP_POP:
      Pop();
      break;
    case PSOP_EXCH:
      d2 = Pop();
      d1 = Pop();
      Push(d2);
      Push(d1);
      break;
    case PSOP_DUP:
      d1 = Pop();
      Push(d1);
      Push(d1);
      break;
    case PSOP_COPY: {
      int n = (int)Pop();
      if (n < 0 || n > PSENGINE_STACKSIZE ||
          m_StackCount + n > PSENGINE_STACKSIZE || n > m_StackCount) {
        break;
      }
      for (int i = 0; i < n; i++) {
        m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
      }
      m_StackCount += n;
      break;
    }
    case PSOP_INDEX: {
      int n = (int)Pop();
      if (n < 0 || n >= m_StackCount) {
        break;
      }
      Push(m_Stack[m_StackCount - n - 1]);
      break;
    }
    case PSOP_ROLL: {
      int j = (int)Pop();
      int n = (int)Pop();
      if (m_StackCount == 0) {
        break;
      }
      if (n < 0 || n > m_StackCount) {
        break;
      }
      if (j < 0)
        for (int i = 0; i < -j; i++) {
          FX_FLOAT first = m_Stack[m_StackCount - n];
          for (int ii = 0; ii < n - 1; ii++) {
            m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1];
          }
          m_Stack[m_StackCount - 1] = first;
        }
      else
        for (int i = 0; i < j; i++) {
          FX_FLOAT last = m_Stack[m_StackCount - 1];
          int ii;
          for (ii = 0; ii < n - 1; ii++) {
            m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2];
          }
          m_Stack[m_StackCount - ii - 1] = last;
        }
      break;
    }
    default:
      break;
  }
  return TRUE;
}