示例#1
0
void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
        int left,
        int top,
        FX_ARGB mask_argb,
        int bitmap_alpha,
        int blend_mode,
        int Transparency) {
    if (pDIBitmap == NULL) {
        return;
    }
    FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED;
    FX_BOOL bGroup = Transparency & PDFTRANS_GROUP;
    if (blend_mode == FXDIB_BLEND_NORMAL) {
        if (!pDIBitmap->IsAlphaMask()) {
            if (bitmap_alpha < 255) {
                pDIBitmap->MultiplyAlpha(bitmap_alpha);
            }
            if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
                return;
            }
        } else {
            FX_DWORD fill_argb = m_Options.TranslateColor(mask_argb);
            if (bitmap_alpha < 255) {
                ((uint8_t*)&fill_argb)[3] =
                    ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255;
            }
            if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
                return;
            }
        }
    }
    FX_BOOL bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects;
    FX_BOOL bGetBackGround =
        ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
        (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
         (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired);
    if (bGetBackGround) {
        if (bIsolated || !bGroup) {
            if (pDIBitmap->IsAlphaMask()) {
                return;
            }
            m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
        } else {
            FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
                         top + pDIBitmap->GetHeight());
            rect.Intersect(m_pDevice->GetClipBox());
            CFX_DIBitmap* pClone = NULL;
            FX_BOOL bClone = FALSE;
            if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
                bClone = TRUE;
                pClone = m_pDevice->GetBackDrop()->Clone(&rect);
                CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap();
                pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                                        pForeBitmap, rect.left, rect.top);
                left = left >= 0 ? 0 : left;
                top = top >= 0 ? 0 : top;
                if (!pDIBitmap->IsAlphaMask())
                    pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                                            pDIBitmap, left, top, blend_mode);
                else
                    pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                                          pDIBitmap, mask_argb, left, top, blend_mode);
            } else {
                pClone = pDIBitmap;
            }
            if (m_pDevice->GetBackDrop()) {
                m_pDevice->SetDIBits(pClone, rect.left, rect.top);
            } else {
                if (pDIBitmap->IsAlphaMask()) {
                    return;
                }
                m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
            }
            if (bClone) {
                delete pClone;
            }
        }
        return;
    }
    int back_left, back_top;
    FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
                 top + pDIBitmap->GetHeight());
    nonstd::unique_ptr<CFX_DIBitmap> pBackdrop(
        GetBackdrop(m_pCurObj, rect, back_left, back_top,
                    blend_mode > FXDIB_BLEND_NORMAL && bIsolated));
    if (!pBackdrop)
        return;

    if (!pDIBitmap->IsAlphaMask()) {
        pBackdrop->CompositeBitmap(left - back_left, top - back_top,
                                   pDIBitmap->GetWidth(), pDIBitmap->GetHeight(),
                                   pDIBitmap, 0, 0, blend_mode);
    } else {
        pBackdrop->CompositeMask(left - back_left, top - back_top,
                                 pDIBitmap->GetWidth(), pDIBitmap->GetHeight(),
                                 pDIBitmap, mask_argb, 0, 0, blend_mode);
    }

    nonstd::unique_ptr<CFX_DIBitmap> pBackdrop1(new CFX_DIBitmap);
    pBackdrop1->Create(pBackdrop->GetWidth(), pBackdrop->GetHeight(),
                       FXDIB_Rgb32);
    pBackdrop1->Clear((FX_DWORD)-1);
    pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(),
                                pBackdrop->GetHeight(), pBackdrop.get(), 0, 0);
    pBackdrop = nonstd::move(pBackdrop1);
    m_pDevice->SetDIBits(pBackdrop.get(), back_left, back_top);
}
void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern,
                                    CFX_Matrix* pMatrix,
                                    FX_RECT& clip_rect,
                                    int alpha,
                                    FX_BOOL bAlphaMode) {
  CPDF_Function** pFuncs = pPattern->m_pFunctions;
  int nFuncs = pPattern->m_nFuncs;
  CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict();
  CPDF_ColorSpace* pColorSpace = pPattern->m_pCS;
  if (!pColorSpace) {
    return;
  }
  FX_ARGB background = 0;
  if (!pPattern->m_bShadingObj &&
      pPattern->m_pShadingObj->GetDict()->KeyExist("Background")) {
    CPDF_Array* pBackColor =
        pPattern->m_pShadingObj->GetDict()->GetArray("Background");
    if (pBackColor &&
        pBackColor->GetCount() >= (FX_DWORD)pColorSpace->CountComponents()) {
      CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents());
      for (int i = 0; i < pColorSpace->CountComponents(); i++) {
        comps[i] = pBackColor->GetNumber(i);
      }
      FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
      pColorSpace->GetRGB(comps, R, G, B);
      background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255),
                              (int32_t)(B * 255));
    }
  }
  if (pDict->KeyExist("BBox")) {
    CFX_FloatRect rect = pDict->GetRect("BBox");
    rect.Transform(pMatrix);
    clip_rect.Intersect(rect.GetOutterRect());
  }
  CPDF_DeviceBuffer buffer;
  buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150);
  CFX_Matrix FinalMatrix = *pMatrix;
  FinalMatrix.Concat(*buffer.GetMatrix());
  CFX_DIBitmap* pBitmap = buffer.GetBitmap();
  if (!pBitmap->GetBuffer()) {
    return;
  }
  pBitmap->Clear(background);
  int fill_mode = m_Options.m_Flags;
  switch (pPattern->m_ShadingType) {
    case kInvalidShading:
    case kMaxShading:
      return;
    case kFunctionBasedShading:
      DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace,
                      alpha);
      break;
    case kAxialShading:
      DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
                       pColorSpace, alpha);
      break;
    case kRadialShading:
      DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
                        pColorSpace, alpha);
      break;
    case kFreeFormGouraudTriangleMeshShading: {
      DrawFreeGouraudShading(pBitmap, &FinalMatrix,
                             ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs,
                             pColorSpace, alpha);
    } break;
    case kLatticeFormGouraudTriangleMeshShading: {
      DrawLatticeGouraudShading(pBitmap, &FinalMatrix,
                                ToStream(pPattern->m_pShadingObj), pFuncs,
                                nFuncs, pColorSpace, alpha);
    } break;
    case kCoonsPatchMeshShading:
    case kTensorProductPatchMeshShading: {
      DrawCoonPatchMeshes(
          pPattern->m_ShadingType == kTensorProductPatchMeshShading, pBitmap,
          &FinalMatrix, ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs,
          pColorSpace, fill_mode, alpha);
    } break;
  }
  if (bAlphaMode) {
    pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha);
  }
  if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
    pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor);
  }
  buffer.OutputToDevice();
}
CFX_DIBitmap* CFX_DIBSource::SwapXY(FX_BOOL bXFlip,
                                    FX_BOOL bYFlip,
                                    const FX_RECT* pDestClip) const {
  FX_RECT dest_clip(0, 0, m_Height, m_Width);
  if (pDestClip) {
    dest_clip.Intersect(*pDestClip);
  }
  if (dest_clip.IsEmpty()) {
    return nullptr;
  }
  CFX_DIBitmap* pTransBitmap = new CFX_DIBitmap;
  int result_height = dest_clip.Height(), result_width = dest_clip.Width();
  if (!pTransBitmap->Create(result_width, result_height, GetFormat())) {
    delete pTransBitmap;
    return nullptr;
  }
  pTransBitmap->CopyPalette(m_pPalette);
  int dest_pitch = pTransBitmap->GetPitch();
  uint8_t* dest_buf = pTransBitmap->GetBuffer();
  int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left;
  int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right;
  int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top;
  int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom;
  if (GetBPP() == 1) {
    FXSYS_memset(dest_buf, 0xff, dest_pitch * result_height);
    for (int row = row_start; row < row_end; row++) {
      const uint8_t* src_scan = GetScanline(row);
      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
                     dest_clip.left;
      uint8_t* dest_scan = dest_buf;
      if (bYFlip) {
        dest_scan += (result_height - 1) * dest_pitch;
      }
      int dest_step = bYFlip ? -dest_pitch : dest_pitch;
      for (int col = col_start; col < col_end; col++) {
        if (!(src_scan[col / 8] & (1 << (7 - col % 8)))) {
          dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8));
        }
        dest_scan += dest_step;
      }
    }
  } else {
    int nBytes = GetBPP() / 8;
    int dest_step = bYFlip ? -dest_pitch : dest_pitch;
    if (nBytes == 3) {
      dest_step -= 2;
    }
    for (int row = row_start; row < row_end; row++) {
      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
                     dest_clip.left;
      uint8_t* dest_scan = dest_buf + dest_col * nBytes;
      if (bYFlip) {
        dest_scan += (result_height - 1) * dest_pitch;
      }
      if (nBytes == 4) {
        uint32_t* src_scan = (uint32_t*)GetScanline(row) + col_start;
        for (int col = col_start; col < col_end; col++) {
          *(uint32_t*)dest_scan = *src_scan++;
          dest_scan += dest_step;
        }
      } else {
        const uint8_t* src_scan = GetScanline(row) + col_start * nBytes;
        if (nBytes == 1) {
          for (int col = col_start; col < col_end; col++) {
            *dest_scan = *src_scan++;
            dest_scan += dest_step;
          }
        } else {
          for (int col = col_start; col < col_end; col++) {
            *dest_scan++ = *src_scan++;
            *dest_scan++ = *src_scan++;
            *dest_scan = *src_scan++;
            dest_scan += dest_step;
          }
        }
      }
    }
  }
  if (m_pAlphaMask) {
    dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch();
    dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer();
    int dest_step = bYFlip ? -dest_pitch : dest_pitch;
    for (int row = row_start; row < row_end; row++) {
      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
                     dest_clip.left;
      uint8_t* dest_scan = dest_buf + dest_col;
      if (bYFlip) {
        dest_scan += (result_height - 1) * dest_pitch;
      }
      const uint8_t* src_scan = m_pAlphaMask->GetScanline(row) + col_start;
      for (int col = col_start; col < col_end; col++) {
        *dest_scan = *src_scan++;
        dest_scan += dest_step;
      }
    }
  }
  return pTransBitmap;
}
示例#4
0
STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun(
    const FX_RECT& text_bbox,
    __in_opt CFX_ClipRgn* pClipRgn,
    __in_opt DWRITE_MATRIX const* pMatrix,
    FLOAT baselineOriginX,
    FLOAT baselineOriginY,
    DWRITE_MEASURING_MODE measuringMode,
    __in DWRITE_GLYPH_RUN const* glyphRun,
    const COLORREF& textColor
)
{
    HRESULT hr = S_OK;
    if (pMatrix) {
        hr = pRenderTarget_->SetCurrentTransform(pMatrix);
        if (FAILED(hr)) {
            return hr;
        }
    }
    HDC hDC = pRenderTarget_->GetMemoryDC();
    HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP);
    BITMAP bitmap;
    GetObject(hBitmap, sizeof bitmap, &bitmap);
    CFX_DIBitmap dib;
    dib.Create(
        bitmap.bmWidth,
        bitmap.bmHeight,
        bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32,
        (FX_LPBYTE)bitmap.bmBits
    );
    dib.CompositeBitmap(
        text_bbox.left,
        text_bbox.top,
        text_bbox.Width(),
        text_bbox.Height(),
        pBitmap_,
        text_bbox.left,
        text_bbox.top,
        FXDIB_BLEND_NORMAL,
        NULL
    );
    hr = pRenderTarget_->DrawGlyphRun(
             baselineOriginX,
             baselineOriginY,
             measuringMode,
             glyphRun,
             pRenderingParams_,
             textColor
         );
    if (FAILED(hr)) {
        return hr;
    }
    pBitmap_->CompositeBitmap(
        text_bbox.left,
        text_bbox.top,
        text_bbox.Width(),
        text_bbox.Height(),
        &dib,
        text_bbox.left,
        text_bbox.top,
        FXDIB_BLEND_NORMAL,
        pClipRgn
    );
    return hr;
}
CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette, FX_DWORD palsize)
{
    FX_BOOL bCreatedDC = hDC == NULL;
    if (hDC == NULL) {
        hDC = CreateCompatibleDC(NULL);
    }
    BITMAPINFOHEADER bmih;
    FXSYS_memset(&bmih, 0, sizeof bmih);
    bmih.biSize = sizeof bmih;
    GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
    int width = bmih.biWidth;
    int height = abs(bmih.biHeight);
    bmih.biHeight = -height;
    bmih.biCompression = BI_RGB;
    CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap;
    int ret = 0;
    if (bmih.biBitCount == 1 || bmih.biBitCount == 8) {
        int size = sizeof (BITMAPINFOHEADER) + 8;
        if (bmih.biBitCount == 8) {
            size += sizeof (FX_DWORD) * 254;
        }
        BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(uint8_t, size);
        pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pbmih->bmiHeader.biBitCount = bmih.biBitCount;
        pbmih->bmiHeader.biCompression = BI_RGB;
        pbmih->bmiHeader.biHeight = -height;
        pbmih->bmiHeader.biPlanes = 1;
        pbmih->bmiHeader.biWidth = bmih.biWidth;
        if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) {
            delete pDIBitmap;
            FX_Free(pbmih);
            if (bCreatedDC) {
                DeleteDC(hDC);
            }
            return NULL;
        }
        ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)pbmih, DIB_RGB_COLORS);
        FX_Free(pbmih);
        pbmih = NULL;
        pDIBitmap->CopyPalette(pPalette, palsize);
    } else {
        if (bmih.biBitCount <= 24) {
            bmih.biBitCount = 24;
        } else {
            bmih.biBitCount = 32;
        }
        if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) {
            delete pDIBitmap;
            if (bCreatedDC) {
                DeleteDC(hDC);
            }
            return NULL;
        }
        ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
        if (ret != 0 && bmih.biBitCount == 32) {
            int pitch = pDIBitmap->GetPitch();
            for (int row = 0; row < height; row ++) {
                uint8_t* dest_scan = (uint8_t*)(pDIBitmap->GetBuffer() + row * pitch);
                for (int col = 0; col < width; col++) {
                    dest_scan[3] = 255;
                    dest_scan += 4;
                }
            }
        }
    }
    if (ret == 0) {
        delete pDIBitmap;
        pDIBitmap = NULL;
    }
    if (bCreatedDC) {
        DeleteDC(hDC);
    }
    return pDIBitmap;
}
示例#6
0
FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device)
{
    CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->GetType3Font();
    for (int j = 0; j < m_Type3FontCache.GetSize(); j++)
        if ((CPDF_Type3Font*)m_Type3FontCache.GetAt(j) == pType3Font) {
            return TRUE;
        }
    CFX_Matrix dCTM = m_pDevice->GetCTM();
    FX_FLOAT sa = FXSYS_fabs(dCTM.a);
    FX_FLOAT sd = FXSYS_fabs(dCTM.d);
    CFX_AffineMatrix text_matrix;
    textobj->GetTextMatrix(&text_matrix);
    CFX_AffineMatrix char_matrix = pType3Font->GetFontMatrix();
    FX_FLOAT font_size = textobj->m_TextState.GetFontSize();
    char_matrix.Scale(font_size, font_size);
    FX_ARGB fill_argb = GetFillArgb(textobj, TRUE);
    int fill_alpha = FXARGB_A(fill_argb);
    int device_class = m_pDevice->GetDeviceClass();
    FXTEXT_GLYPHPOS* pGlyphAndPos = NULL;
    if (device_class == FXDC_DISPLAY) {
        pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, textobj->m_nChars);
    } else if (fill_alpha < 255) {
        return FALSE;
    }
    CPDF_RefType3Cache refTypeCache(pType3Font);
    FX_DWORD *pChars = textobj->m_pCharCodes;
    if (textobj->m_nChars == 1) {
        pChars = (FX_DWORD*)(&textobj->m_pCharCodes);
    }
    for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) {
        FX_DWORD charcode = pChars[iChar];
        if (charcode == (FX_DWORD) - 1) {
            continue;
        }
        CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode);
        if (pType3Char == NULL) {
            continue;
        }
        CFX_AffineMatrix matrix = char_matrix;
        matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0;
        matrix.Concat(text_matrix);
        matrix.Concat(*pObj2Device);
        if (!pType3Char->LoadBitmap(m_pContext)) {
            if (pGlyphAndPos) {
                for (int i = 0; i < iChar; i ++) {
                    FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[i];
                    if (glyph.m_pGlyph == NULL) {
                        continue;
                    }
                    m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap,
                                          glyph.m_OriginX + glyph.m_pGlyph->m_Left,
                                          glyph.m_OriginY - glyph.m_pGlyph->m_Top, fill_argb);
                }
                FX_Free(pGlyphAndPos);
                pGlyphAndPos = NULL;
            }
            CPDF_GraphicStates* pStates = CloneObjStates(textobj, FALSE);
            CPDF_RenderOptions Options = m_Options;
            Options.m_Flags |= RENDER_FORCE_HALFTONE | RENDER_RECT_AA;
            Options.m_Flags &= ~RENDER_FORCE_DOWNSAMPLE;
            CPDF_Dictionary* pFormResource = NULL;
            if (pType3Char->m_pForm && pType3Char->m_pForm->m_pFormDict) {
                pFormResource = pType3Char->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
            }
            if (fill_alpha == 255) {
                CPDF_RenderStatus status;
                status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates, &Options,
                                  pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb);
                status.m_Type3FontCache.Append(m_Type3FontCache);
                status.m_Type3FontCache.Add(pType3Font);
                m_pDevice->SaveState();
                status.RenderObjectList(pType3Char->m_pForm, &matrix);
                m_pDevice->RestoreState();
            } else {
                CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox();
                rect_f.Transform(&matrix);
                FX_RECT rect = rect_f.GetOutterRect();
                CFX_FxgeDevice bitmap_device;
                if (!bitmap_device.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_Argb)) {
                    return TRUE;
                }
                bitmap_device.GetBitmap()->Clear(0);
                CPDF_RenderStatus status;
                status.Initialize(m_pContext, &bitmap_device, NULL, NULL, this, pStates, &Options,
                                  pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb);
                status.m_Type3FontCache.Append(m_Type3FontCache);
                status.m_Type3FontCache.Add(pType3Font);
                matrix.TranslateI(-rect.left, -rect.top);
                matrix.Scale(sa, sd);
                status.RenderObjectList(pType3Char->m_pForm, &matrix);
                m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top);
            }
            delete pStates;
        } else if (pType3Char->m_pBitmap) {
            if (device_class == FXDC_DISPLAY) {
                CPDF_Type3Cache* pCache = GetCachedType3(pType3Font);
                refTypeCache.m_dwCount++;
                CFX_GlyphBitmap* pBitmap = pCache->LoadGlyph(charcode, &matrix, sa, sd);
                if (pBitmap == NULL) {
                    continue;
                }
                int origin_x = FXSYS_round(matrix.e);
                int origin_y = FXSYS_round(matrix.f);
                if (pGlyphAndPos) {
                    pGlyphAndPos[iChar].m_pGlyph = pBitmap;
                    pGlyphAndPos[iChar].m_OriginX = origin_x;
                    pGlyphAndPos[iChar].m_OriginY = origin_y;
                } else {
                    m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left, origin_y - pBitmap->m_Top, fill_argb);
                }
            } else {
                CFX_AffineMatrix image_matrix = pType3Char->m_ImageMatrix;
                image_matrix.Concat(matrix);
                CPDF_ImageRenderer renderer;
                if (renderer.Start(this, pType3Char->m_pBitmap, fill_argb, 255, &image_matrix, 0, FALSE)) {
                    renderer.Continue(NULL);
                }
                if (!renderer.m_Result) {
                    return FALSE;
                }
            }
        }
    }
    if (pGlyphAndPos) {
        FX_RECT rect = FXGE_GetGlyphsBBox(pGlyphAndPos, textobj->m_nChars, 0, sa, sd);
        CFX_DIBitmap bitmap;
        if (!bitmap.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_8bppMask)) {
            FX_Free(pGlyphAndPos);
            return TRUE;
        }
        bitmap.Clear(0);
        for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) {
            FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
            if (glyph.m_pGlyph == NULL) {
                continue;
            }
            bitmap.TransferBitmap((int)((glyph.m_OriginX + glyph.m_pGlyph->m_Left - rect.left) * sa),
                                  (int)((glyph.m_OriginY - glyph.m_pGlyph->m_Top - rect.top) * sd),
                                  glyph.m_pGlyph->m_Bitmap.GetWidth(), glyph.m_pGlyph->m_Bitmap.GetHeight(),
                                  &glyph.m_pGlyph->m_Bitmap, 0, 0);
        }
        m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb);
        FX_Free(pGlyphAndPos);
    }
    return TRUE;
}
CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict,
        FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix)
{
    if (pSMaskDict == NULL) {
        return NULL;
    }
    CFX_DIBitmap* pMask = NULL;
    int width = pClipRect->right - pClipRect->left;
    int height = pClipRect->bottom - pClipRect->top;
    FX_BOOL bLuminosity = FALSE;
    bLuminosity = pSMaskDict->GetConstString(FX_BSTRC("S")) != FX_BSTRC("Alpha");
    CPDF_Stream* pGroup = pSMaskDict->GetStream(FX_BSTRC("G"));
    if (pGroup == NULL) {
        return NULL;
    }
    CPDF_Function* pFunc = NULL;
    CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR"));
    if (pFuncObj && (pFuncObj->GetType() == PDFOBJ_DICTIONARY || pFuncObj->GetType() == PDFOBJ_STREAM)) {
        pFunc = CPDF_Function::Load(pFuncObj);
    }
    CFX_AffineMatrix matrix = *pMatrix;
    matrix.TranslateI(-pClipRect->left, -pClipRect->top);
    CPDF_Form form(m_pContext->m_pDocument, m_pContext->m_pPageResources, pGroup);
    form.ParseContent(NULL, NULL, NULL, NULL);
    CFX_FxgeDevice bitmap_device;
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
    if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask)) {
        return NULL;
    }
#else
    if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask)) {
        return NULL;
    }
#endif
    CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap();
    CPDF_Object* pCSObj = NULL;
    CPDF_ColorSpace* pCS = NULL;
    if (bLuminosity) {
        CPDF_Array* pBC = pSMaskDict->GetArray(FX_BSTRC("BC"));
        FX_ARGB back_color = 0xff000000;
        if (pBC) {
            pCSObj = pGroup->GetDict()->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS"));
            pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj);
            if (pCS) {
                FX_FLOAT R, G, B;
                FX_DWORD num_floats = 8;
                if (pCS->CountComponents() > (FX_INT32)num_floats) {
                    num_floats = (FX_DWORD)pCS->CountComponents();
                }
                CFX_FixedBufGrow<FX_FLOAT, 8> float_array(num_floats);
                FX_FLOAT* pFloats = float_array;
                FXSYS_memset32(pFloats, 0, num_floats * sizeof(FX_FLOAT));
                int count = pBC->GetCount() > 8 ? 8 : pBC->GetCount();
                for (int i = 0; i < count; i ++) {
                    pFloats[i] = pBC->GetNumber(i);
                }
                pCS->GetRGB(pFloats, R, G, B);
                back_color = 0xff000000 | ((FX_INT32)(R * 255) << 16) | ((FX_INT32)(G * 255) << 8) | (FX_INT32)(B * 255);
                m_pContext->m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
            }
        }
        bitmap.Clear(back_color);
    } else {
        bitmap.Clear(0);
    }
    CPDF_Dictionary* pFormResource = NULL;
    if (form.m_pFormDict) {
        pFormResource = form.m_pFormDict->GetDict(FX_BSTRC("Resources"));
    }
    CPDF_RenderOptions options;
    options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA;
    CPDF_RenderStatus status;
    status.Initialize(m_Level + 1, m_pContext, &bitmap_device, NULL, NULL, NULL, NULL,
                      &options, 0, m_bDropObjects, pFormResource, TRUE, NULL, 0, pCS ? pCS->GetFamily() : 0, bLuminosity);
    status.RenderObjectList(&form, &matrix);
    pMask = FX_NEW CFX_DIBitmap;
    if (!pMask->Create(width, height, FXDIB_8bppMask)) {
        delete pMask;
        return NULL;
    }
    FX_LPBYTE dest_buf = pMask->GetBuffer();
    int dest_pitch = pMask->GetPitch();
    FX_LPBYTE src_buf = bitmap.GetBuffer();
    int src_pitch = bitmap.GetPitch();
    FX_LPBYTE pTransfer = FX_Alloc(FX_BYTE, 256);
    if (pFunc) {
        CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs());
        for (int i = 0; i < 256; i ++) {
            FX_FLOAT input = (FX_FLOAT)i / 255.0f;
            int nresult;
            pFunc->Call(&input, 1, results, nresult);
            pTransfer[i] = FXSYS_round(results[0] * 255);
        }
    } else {
        for (int i = 0; i < 256; i ++) {
            pTransfer[i] = i;
        }
    }
    if (bLuminosity) {
        int Bpp = bitmap.GetBPP() / 8;
        for (int row = 0; row < height; row ++) {
            FX_LPBYTE dest_pos = dest_buf + row * dest_pitch;
            FX_LPBYTE src_pos = src_buf + row * src_pitch;
            for (int col = 0; col < width; col ++) {
                *dest_pos ++ = pTransfer[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)];
                src_pos += Bpp;
            }
        }
    } else if (pFunc) {
        int size = dest_pitch * height;
        for (int i = 0; i < size; i ++) {
            dest_buf[i] = pTransfer[src_buf[i]];
        }
    } else {
        FXSYS_memcpy32(dest_buf, src_buf, dest_pitch * height);
    }
    if (pFunc) {
        delete pFunc;
    }
    FX_Free(pTransfer);
    return pMask;
}
示例#8
0
FWL_ERR CFWL_PushButtonImp::DrawWidget(CFX_Graphics* pGraphics,
                                       const CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return FWL_ERR_Indefinite;
  if (!m_pProperties->m_pThemeProvider)
    return FWL_ERR_Indefinite;
  IFWL_PushButtonDP* pData =
      static_cast<IFWL_PushButtonDP*>(m_pProperties->m_pDataProvider);
  CFX_DIBitmap* pPicture = NULL;
  IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
  if (HasBorder()) {
    DrawBorder(pGraphics, FWL_PART_PSB_Border, m_pProperties->m_pThemeProvider,
               pMatrix);
  }
  if (HasEdge()) {
    DrawEdge(pGraphics, FWL_PART_PSB_Edge, m_pProperties->m_pThemeProvider,
             pMatrix);
  }
  DrawBkground(pGraphics, m_pProperties->m_pThemeProvider, pMatrix);
  CFX_Matrix matrix;
  matrix.Concat(*pMatrix);
  FX_FLOAT iPicwidth = 0;
  FX_FLOAT ipicheight = 0;
  CFX_WideString wsCaption;
  if (pData) {
    pData->GetCaption(m_pInterface, wsCaption);
  }
  CFX_RectF rtText;
  rtText.Set(0, 0, 0, 0);
  if (!wsCaption.IsEmpty()) {
    CalcTextRect(wsCaption, pTheme, 0, m_iTTOAlign, rtText);
  }
  switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_PSB_ModeMask) {
    case FWL_STYLEEXT_PSB_TextOnly:
      DrawText(pGraphics, m_pProperties->m_pThemeProvider, &matrix);
      break;
    case FWL_STYLEEXT_PSB_IconOnly:
      if (pData) {
        pPicture = pData->GetPicture(m_pInterface);
      }
      if (pPicture) {
        CFX_PointF point;
        switch (m_iTTOAlign) {
          case 0: {
            point.x = m_rtClient.left;
            point.y = m_rtClient.top;
            break;
          }
          case 1: {
            point.x = m_rtClient.left +
                      (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
            point.y = m_rtClient.top;
            break;
          }
          case 2:
            point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
            point.y = m_rtClient.top;
            break;
          case 4:
            point.x = m_rtClient.left;
            point.y = m_rtClient.top + m_rtClient.height / 2 -
                      pPicture->GetHeight() / 2;
            break;
          case 5:
            point.x = m_rtClient.left +
                      (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
            point.y = m_rtClient.top + m_rtClient.height / 2 -
                      pPicture->GetHeight() / 2;
            break;
          case 6:
            point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
            point.y = m_rtClient.top + m_rtClient.height / 2 -
                      pPicture->GetHeight() / 2;
            break;
          case 8:
            point.x = m_rtClient.left;
            point.y =
                m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
            break;
          case 9:
            point.x = m_rtClient.left +
                      (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
            point.y =
                m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
            break;
          case 10:
            point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
            point.y =
                m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
            break;
        }
        pGraphics->DrawImage(pPicture, point, &matrix);
      }
      break;
    case FWL_STYLEEXT_PSB_TextIcon:
      if (pPicture) {
        CFX_PointF point;
        switch (m_iTTOAlign) {
          case 0: {
            point.x = m_rtClient.left;
            point.y = m_rtClient.top;
            iPicwidth = (FX_FLOAT)(pPicture->GetWidth() - 7);
            ipicheight =
                pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
            break;
          }
          case 1: {
            point.x =
                m_rtClient.left + (m_rtClient.width / 2 -
                                   (pPicture->GetWidth() + rtText.width) / 2);
            point.y = m_rtClient.top;
            iPicwidth = pPicture->GetWidth() -
                        ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) +
                        rtText.width / 2 - 7;
            ipicheight =
                pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
            break;
          }
          case 2:
            point.x = m_rtClient.left + m_rtClient.width -
                      pPicture->GetWidth() - rtText.width;
            point.y = m_rtClient.top;
            iPicwidth = m_rtClient.left + m_rtClient.width - point.x -
                        pPicture->GetWidth() - rtText.width + 7;
            ipicheight =
                pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
            break;
          case 4:
            point.x = m_rtClient.left;
            point.y = m_rtClient.top + m_rtClient.height / 2 -
                      pPicture->GetHeight() / 2;
            iPicwidth = m_rtClient.left + pPicture->GetWidth() - 7;
            break;
          case 5:
            point.x =
                m_rtClient.left + (m_rtClient.width / 2 -
                                   (pPicture->GetWidth() + rtText.width) / 2);
            point.y = m_rtClient.top + m_rtClient.height / 2 -
                      pPicture->GetHeight() / 2;
            iPicwidth = pPicture->GetWidth() -
                        ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) +
                        rtText.width / 2 - 7;
            break;
          case 6:
            point.x = m_rtClient.left + m_rtClient.width -
                      pPicture->GetWidth() - rtText.width;
            point.y = m_rtClient.top + m_rtClient.height / 2 -
                      pPicture->GetHeight() / 2;
            iPicwidth = m_rtClient.left + m_rtClient.width - point.x -
                        pPicture->GetWidth() - rtText.width + 7;
            break;
          case 8:
            point.x = m_rtClient.left;
            point.y =
                m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
            iPicwidth = (FX_FLOAT)(pPicture->GetWidth() - 7);
            ipicheight -= rtText.height / 2;
            break;
          case 9:
            point.x =
                m_rtClient.left + (m_rtClient.width / 2 -
                                   (pPicture->GetWidth() + rtText.width) / 2);
            point.y =
                m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
            iPicwidth = pPicture->GetWidth() -
                        ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) +
                        rtText.width / 2 - 7;
            ipicheight -= rtText.height / 2;
            break;
          case 10:
            point.x = m_rtClient.left + m_rtClient.width -
                      pPicture->GetWidth() - rtText.width;
            point.y =
                m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
            iPicwidth = m_rtClient.left + m_rtClient.width - point.x -
                        pPicture->GetWidth() - rtText.width + 7;
            ipicheight -= rtText.height / 2;
            break;
        }
        pGraphics->DrawImage(pPicture, point, &matrix);
      }
      matrix.e += m_rtClient.left + iPicwidth;
      matrix.f += m_rtClient.top + ipicheight;
      DrawText(pGraphics, m_pProperties->m_pThemeProvider, &matrix);
      break;
  }
  return FWL_ERR_Succeeded;
}
示例#9
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;
}
static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix)
{
    ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || pSrc->GetFormat() == FXDIB_1bppMask || pSrc->GetFormat() == FXDIB_1bppCmyk);
    CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect();
    FX_RECT full_rect = unit_rect.GetOutterRect();
    int full_left = full_rect.left;
    int full_top = full_rect.top;
    CFX_DIBExtractor src_bitmap(pSrc);
    CFX_DIBitmap* pSrcBitmap = src_bitmap;
    if (pSrcBitmap == NULL) {
        return NULL;
    }
    int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight();
    uint8_t* src_buf = pSrcBitmap->GetBuffer();
    FX_DWORD src_pitch = pSrcBitmap->GetPitch();
    FX_FLOAT dest_area = pDestMatrix->GetUnitArea();
    FX_FLOAT area_scale = FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area);
    FX_FLOAT size_scale = FXSYS_sqrt(area_scale);
    CFX_AffineMatrix adjusted_matrix(*pDestMatrix);
    adjusted_matrix.Scale(size_scale, size_scale);
    CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect();
    FX_RECT result_rect = result_rect_f.GetOutterRect();
    CFX_AffineMatrix src2result;
    src2result.e = adjusted_matrix.c + adjusted_matrix.e;
    src2result.f = adjusted_matrix.d + adjusted_matrix.f;
    src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth();
    src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth();
    src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight();
    src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight();
    src2result.TranslateI(-result_rect.left, -result_rect.top);
    CFX_AffineMatrix result2src;
    result2src.SetReverse(src2result);
    CPDF_FixedMatrix result2src_fix(result2src, 8);
    int result_width = result_rect.Width();
    int result_height = result_rect.Height();
    CFX_DIBitmap* pTempBitmap = new CFX_DIBitmap;
    if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) {
        delete pTempBitmap;
        if (pSrcBitmap != src_bitmap) {
            delete pSrcBitmap;
        }
        return NULL;
    }
    pTempBitmap->CopyPalette(pSrc->GetPalette());
    uint8_t* dest_buf = pTempBitmap->GetBuffer();
    int dest_pitch = pTempBitmap->GetPitch();
    FXSYS_memset(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_height);
    if (pSrcBitmap->IsAlphaMask()) {
        for (int dest_y = 0; dest_y < result_height; dest_y ++) {
            uint8_t* dest_scan = dest_buf + dest_y * dest_pitch;
            for (int dest_x = 0; dest_x < result_width; dest_x ++) {
                int src_x, src_y;
                result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
                if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
                    continue;
                }
                if (!((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8)))) {
                    continue;
                }
                dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8);
            }
        }
    } else {
        for (int dest_y = 0; dest_y < result_height; dest_y ++) {
            uint8_t* dest_scan = dest_buf + dest_y * dest_pitch;
            for (int dest_x = 0; dest_x < result_width; dest_x ++) {
                int src_x, src_y;
                result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
                if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
                    continue;
                }
                if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) {
                    continue;
                }
                dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8));
            }
        }
    }
    if (pSrcBitmap != src_bitmap) {
        delete pSrcBitmap;
    }
    return pTempBitmap;
}
示例#11
0
DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width, int height, int alpha)
{
    CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
    pBitmap->Create(width, height, alpha ? FXDIB_Argb : FXDIB_Rgb32);
    return pBitmap;
}
示例#12
0
DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc, FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
                                       int rotate, int flags)
{
    if (page==NULL) return;
    CPDF_Page* pPage = (CPDF_Page*)page;

    CRenderContext* pContext = FX_NEW CRenderContext;
    pPage->SetPrivateData((void*)1, pContext, DropContext);

#ifndef _WIN32_WCE
    CFX_DIBitmap* pBitmap = NULL;
    FX_BOOL bBackgroundAlphaNeeded=FALSE;
    bBackgroundAlphaNeeded = pPage->BackgroundAlphaNeeded();
    if (bBackgroundAlphaNeeded)
    {

        pBitmap = FX_NEW CFX_DIBitmap;
        pBitmap->Create(size_x, size_y, FXDIB_Argb);
        pBitmap->Clear(0x00ffffff);
#ifdef _SKIA_SUPPORT_
        pContext->m_pDevice = FX_NEW CFX_SkiaDevice;
        ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
#else
        pContext->m_pDevice = FX_NEW CFX_FxgeDevice;
        ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
#endif
    }
    else
        pContext->m_pDevice = FX_NEW CFX_WindowsDevice(dc);
    if (flags & FPDF_NO_CATCH)
        Func_RenderPage(pContext, page, start_x, start_y, size_x, size_y, rotate, flags,TRUE,NULL);
    else {
        try {
            Func_RenderPage(pContext, page, start_x, start_y, size_x, size_y, rotate, flags,TRUE,NULL);
        } catch (...) {
        }
    }
    if (bBackgroundAlphaNeeded)
    {
        if (pBitmap)
        {
            CFX_WindowsDevice WinDC(dc);

            if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER)
            {
                CFX_DIBitmap* pDst = FX_NEW CFX_DIBitmap;
                pDst->Create(pBitmap->GetWidth(), pBitmap->GetHeight(),FXDIB_Rgb32);
                FXSYS_memcpy(pDst->GetBuffer(), pBitmap->GetBuffer(), pBitmap->GetPitch()*pBitmap->GetHeight());
//				WinDC.SetDIBits(pDst,0,0);
                WinDC.StretchDIBits(pDst,0,0,size_x*2,size_y*2);
                delete pDst;
            }
            else
                WinDC.SetDIBits(pBitmap,0,0);

        }
    }
#else
    // get clip region
    RECT rect, cliprect;
    rect.left = start_x;
    rect.top = start_y;
    rect.right = start_x + size_x;
    rect.bottom = start_y + size_y;
    GetClipBox(dc, &cliprect);
    IntersectRect(&rect, &rect, &cliprect);
    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;

#ifdef DEBUG_TRACE
    {
        char str[128];
        sprintf(str, "Rendering DIB %d x %d", width, height);
        CPDF_ModuleMgr::Get()->ReportError(999, str);
    }
#endif

    // Create a DIB section
    LPVOID pBuffer;
    BITMAPINFOHEADER bmih;
    FXSYS_memset(&bmih, 0, sizeof bmih);
    bmih.biSize = sizeof bmih;
    bmih.biBitCount = 24;
    bmih.biHeight = -height;
    bmih.biPlanes = 1;
    bmih.biWidth = width;
    pContext->m_hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, &pBuffer, NULL, 0);
    if (pContext->m_hBitmap == NULL) {
#if defined(DEBUG) || defined(_DEBUG)
        char str[128];
        sprintf(str, "Error CreateDIBSection: %d x %d, error code = %d", width, height, GetLastError());
        CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str);
#else
        CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL);
#endif
    }
    FXSYS_memset(pBuffer, 0xff, height*((width*3+3)/4*4));

#ifdef DEBUG_TRACE
    {
        CPDF_ModuleMgr::Get()->ReportError(999, "DIBSection created");
    }
#endif

    // Create a device with this external buffer
    pContext->m_pBitmap = FX_NEW CFX_DIBitmap;
    pContext->m_pBitmap->Create(width, height, FXDIB_Rgb, (FX_LPBYTE)pBuffer);
    pContext->m_pDevice = FX_NEW CPDF_FxgeDevice;
    ((CPDF_FxgeDevice*)pContext->m_pDevice)->Attach(pContext->m_pBitmap);

#ifdef DEBUG_TRACE
    CPDF_ModuleMgr::Get()->ReportError(999, "Ready for PDF rendering");
#endif

    // output to bitmap device
    if (flags & FPDF_NO_CATCH)
        Func_RenderPage(pContext, page, start_x - rect.left, start_y - rect.top, size_x, size_y, rotate, flags);
    else {
        try {
            Func_RenderPage(pContext, page, start_x - rect.left, start_y - rect.top, size_x, size_y, rotate, flags);
        } catch (...) {
        }
    }

#ifdef DEBUG_TRACE
    CPDF_ModuleMgr::Get()->ReportError(999, "Finished PDF rendering");
#endif

    // Now output to real device
    HDC hMemDC = CreateCompatibleDC(dc);
    if (hMemDC == NULL) {
#if defined(DEBUG) || defined(_DEBUG)
        char str[128];
        sprintf(str, "Error CreateCompatibleDC. Error code = %d", GetLastError());
        CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str);
#else
        CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL);
#endif
    }

    HGDIOBJ hOldBitmap = SelectObject(hMemDC, pContext->m_hBitmap);

#ifdef DEBUG_TRACE
    CPDF_ModuleMgr::Get()->ReportError(999, "Ready for screen rendering");
#endif

    BitBlt(dc, rect.left, rect.top, width, height, hMemDC, 0, 0, SRCCOPY);
    SelectObject(hMemDC, hOldBitmap);
    DeleteDC(hMemDC);

#ifdef DEBUG_TRACE
    CPDF_ModuleMgr::Get()->ReportError(999, "Finished screen rendering");
#endif

#endif
    if (bBackgroundAlphaNeeded)
    {
        if (pBitmap)
            delete pBitmap;
        pBitmap = NULL;
    }
    delete pContext;
    pPage->RemovePrivateData((void*)1);
}
示例#13
0
FX_BOOL CFX_ImageTransformer::Continue(IFX_Pause* pPause)
{
    if (m_Status == 1) {
        if (m_Stretcher.Continue(pPause)) {
            return TRUE;
        }
        if (m_Storer.GetBitmap()) {
            m_Storer.Replace(m_Storer.GetBitmap()->SwapXY(m_pMatrix->c > 0, m_pMatrix->b < 0));
        }
        return FALSE;
    } else if (m_Status == 2) {
        return m_Stretcher.Continue(pPause);
    } else if (m_Status != 3) {
        return FALSE;
    }
    if (m_Stretcher.Continue(pPause)) {
        return TRUE;
    }
    int stretch_width = m_StretchClip.Width();
    int stretch_height = m_StretchClip.Height();
    if (m_Storer.GetBitmap() == NULL) {
        return FALSE;
    }
    FX_LPCBYTE stretch_buf = m_Storer.GetBitmap()->GetBuffer();
    FX_LPCBYTE stretch_buf_mask = NULL;
    if (m_Storer.GetBitmap()->m_pAlphaMask) {
        stretch_buf_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetBuffer();
    }
    int stretch_pitch = m_Storer.GetBitmap()->GetPitch();
    CFX_DIBitmap* pTransformed = FX_NEW CFX_DIBitmap;
    if (!pTransformed) {
        return FALSE;
    }
    FXDIB_Format transformF = _GetTransformedFormat(m_Stretcher.m_pSource);
    if (!pTransformed->Create(m_ResultWidth, m_ResultHeight, transformF)) {
        delete pTransformed;
        return FALSE;
    }
    pTransformed->Clear(0);
    if (pTransformed->m_pAlphaMask) {
        pTransformed->m_pAlphaMask->Clear(0);
    }
    CFX_AffineMatrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, (FX_FLOAT)(m_ResultLeft), (FX_FLOAT)(m_ResultTop));
    result2stretch.Concat(m_dest2stretch);
    result2stretch.TranslateI(-m_StretchClip.left, -m_StretchClip.top);
    if (stretch_buf_mask == NULL && pTransformed->m_pAlphaMask) {
        pTransformed->m_pAlphaMask->Clear(0xff000000);
    } else if (pTransformed->m_pAlphaMask) {
        int stretch_pitch_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetPitch();
        if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
            CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
            for (int row = 0; row < m_ResultHeight; row ++) {
                FX_BYTE* dest_pos_mask = (FX_BYTE*)pTransformed->m_pAlphaMask->GetScanline(row);
                for (int col = 0; col < m_ResultWidth; col ++) {
                    int src_col_l, src_row_l, res_x, res_y;
                    result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
                    if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
                        if (src_col_l == stretch_width) {
                            src_col_l--;
                        }
                        if (src_row_l == stretch_height) {
                            src_row_l--;
                        }
                        int src_col_r = src_col_l + 1;
                        int src_row_r = src_row_l + 1;
                        if (src_col_r == stretch_width) {
                            src_col_r--;
                        }
                        if (src_row_r == stretch_height) {
                            src_row_r--;
                        }
                        int row_offset_l = src_row_l * stretch_pitch_mask;
                        int row_offset_r = src_row_r * stretch_pitch_mask;
                        *dest_pos_mask = _bilinear_interpol(stretch_buf_mask, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0);
                    }
                    dest_pos_mask++;
                }
            }
        } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
            CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
            int pos_pixel[8];
            for (int row = 0; row < m_ResultHeight; row ++) {
                FX_BYTE* dest_pos_mask = (FX_BYTE*)pTransformed->m_pAlphaMask->GetScanline(row);
                for (int col = 0; col < m_ResultWidth; col ++) {
                    int src_col_l, src_row_l, res_x, res_y;
                    result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
                    if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
                        int u_w[4], v_w[4];
                        if (src_col_l == stretch_width) {
                            src_col_l--;
                        }
                        if (src_row_l == stretch_height) {
                            src_row_l--;
                        }
                        _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
                        *dest_pos_mask = _bicubic_interpol(stretch_buf_mask, stretch_pitch_mask, pos_pixel, u_w, v_w, res_x, res_y, 1, 0);
                    }
                    dest_pos_mask++;
                }
            }
        } else {
            CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
            for (int row = 0; row < m_ResultHeight; row ++) {
                FX_BYTE* dest_pos_mask = (FX_BYTE*)pTransformed->m_pAlphaMask->GetScanline(row);
                for (int col = 0; col < m_ResultWidth; col ++) {
                    int src_col, src_row;
                    result2stretch_fix.Transform(col, row, src_col, src_row);
                    if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
                        if (src_col == stretch_width) {
                            src_col --;
                        }
                        if (src_row == stretch_height) {
                            src_row --;
                        }
                        *dest_pos_mask = stretch_buf_mask[src_row * stretch_pitch_mask + src_col];
                    }
                    dest_pos_mask++;
                }
            }
        }
    }
    if (m_Storer.GetBitmap()->IsAlphaMask()) {
        if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
            CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
            for (int row = 0; row < m_ResultHeight; row ++) {
                FX_LPBYTE dest_scan = (FX_LPBYTE)pTransformed->GetScanline(row);
                for (int col = 0; col < m_ResultWidth; col ++) {
                    int src_col_l, src_row_l, res_x, res_y;
                    result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
                    if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
                        if (src_col_l == stretch_width) {
                            src_col_l--;
                        }
                        if (src_row_l == stretch_height) {
                            src_row_l--;
                        }
                        int src_col_r = src_col_l + 1;
                        int src_row_r = src_row_l + 1;
                        if (src_col_r == stretch_width) {
                            src_col_r--;
                        }
                        if (src_row_r == stretch_height) {
                            src_row_r--;
                        }
                        int row_offset_l = src_row_l * stretch_pitch;
                        int row_offset_r = src_row_r * stretch_pitch;
                        *dest_scan = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0);
                    }
                    dest_scan ++;
                }
            }
        } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
            CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
            int pos_pixel[8];
            for (int row = 0; row < m_ResultHeight; row ++) {
                FX_LPBYTE dest_scan = (FX_LPBYTE)pTransformed->GetScanline(row);
                for (int col = 0; col < m_ResultWidth; col ++) {
                    int src_col_l, src_row_l, res_x, res_y;
                    result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
                    if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
                        int u_w[4], v_w[4];
                        if (src_col_l == stretch_width) {
                            src_col_l--;
                        }
                        if (src_row_l == stretch_height) {
                            src_row_l--;
                        }
                        _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
                        *dest_scan = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, 1, 0);
                    }
                    dest_scan ++;
                }
            }
        } else {
            CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
            for (int row = 0; row < m_ResultHeight; row ++) {
                FX_LPBYTE dest_scan = (FX_LPBYTE)pTransformed->GetScanline(row);
                for (int col = 0; col < m_ResultWidth; col ++) {
                    int src_col, src_row;
                    result2stretch_fix.Transform(col, row, src_col, src_row);
                    if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
                        if (src_col == stretch_width) {
                            src_col --;
                        }
                        if (src_row == stretch_height) {
                            src_row --;
                        }
                        FX_LPCBYTE src_pixel = stretch_buf + stretch_pitch * src_row + src_col;
                        *dest_scan = *src_pixel;
                    }
                    dest_scan ++;
                }
            }
        }
    } else {
        int Bpp = m_Storer.GetBitmap()->GetBPP() / 8;
        int destBpp = pTransformed->GetBPP() / 8;
        if (Bpp == 1) {
            FX_BOOL bHasAlpha = m_Storer.GetBitmap()->HasAlpha();
            FX_DWORD argb[256];
            FX_ARGB* pPal = m_Storer.GetBitmap()->GetPalette();
            if (pPal) {
                for (int i = 0; i < 256; i ++) {
                    argb[i] = pPal[i];
                }
            } else {
                if (m_Storer.GetBitmap()->IsCmykImage())
                    for (int i = 0; i < 256; i ++) {
                        argb[i] = 255 - i;
                    }
                else
                    for (int i = 0; i < 256; i ++) {
                        argb[i] = 0xff000000 | (i * 0x010101);
                    }
            }
            if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
                CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
                for (int row = 0; row < m_ResultHeight; row ++) {
                    FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
                    for (int col = 0; col < m_ResultWidth; col ++) {
                        int src_col_l, src_row_l, res_x, res_y;
                        result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
                        if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
                            if (src_col_l == stretch_width) {
                                src_col_l--;
                            }
                            if (src_row_l == stretch_height) {
                                src_row_l--;
                            }
                            int src_col_r = src_col_l + 1;
                            int src_row_r = src_row_l + 1;
                            if (src_col_r == stretch_width) {
                                src_col_r--;
                            }
                            if (src_row_r == stretch_height) {
                                src_row_r--;
                            }
                            int row_offset_l = src_row_l * stretch_pitch;
                            int row_offset_r = src_row_r * stretch_pitch;
                            FX_DWORD r_bgra_cmyk = argb[_bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0)];
                            if (transformF == FXDIB_Rgba) {
                                dest_pos[0] = (FX_BYTE)(r_bgra_cmyk >> 24);
                                dest_pos[1] = (FX_BYTE)(r_bgra_cmyk >> 16);
                                dest_pos[2] = (FX_BYTE)(r_bgra_cmyk >> 8);
                            } else {
                                *(FX_DWORD*)dest_pos = r_bgra_cmyk;
                            }
                        }
                        dest_pos += destBpp;
                    }
                }