Ejemplo n.º 1
0
FX_BOOL CFX_PSRenderer::DrawText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
                                 CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device,
                                 FX_FLOAT font_size, FX_DWORD color,
                                 int alpha_flag, void* pIccTransform)
{
    StartRendering();
    int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
    if (alpha < 255) {
        return FALSE;
    }
    if ((pObject2Device->a == 0 && pObject2Device->b == 0) || (pObject2Device->c == 0 && pObject2Device->d == 0)) {
        return TRUE;
    }
    SetColor(color, alpha_flag, pIccTransform);
    CFX_ByteTextBuf buf;
    buf << FX_BSTRC("q[") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ")
        << pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d;
    buf << FX_BSTRC(" ") << pObject2Device->e << FX_BSTRC(" ") << pObject2Device->f << "]cm\n";
    if (pCache == NULL) {
        pCache = CFX_GEModule::Get()->GetFontCache();
    }
    CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
    FX_FONTCACHE_DEFINE(pCache, pFont);
    int last_fontnum = -1;
    for (int i = 0; i < nChars; i ++) {
        int ps_fontnum, ps_glyphindex;
        FindPSFontGlyph(pFaceCache, pFont, pCharPos[i], ps_fontnum, ps_glyphindex);
        if (last_fontnum != ps_fontnum) {
            buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff ") << font_size
                << FX_BSTRC(" Fs Sf ");
            last_fontnum = ps_fontnum;
        }
        buf << pCharPos[i].m_OriginX << FX_BSTRC(" ")
            << pCharPos[i].m_OriginY << FX_BSTRC(" m");
        CFX_ByteString hex;
        hex.Format("<%02X>", ps_glyphindex);
        buf << hex << FX_BSTRC("Tj\n");
    }
    buf << FX_BSTRC("Q\n");
    m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
    return TRUE;
}
Ejemplo n.º 2
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_Level + 1, 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_Level + 1, 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;
}
Ejemplo n.º 3
0
bool CFX_RenderDevice::DrawPathWithBlend(const CFX_PathData* pPathData,
                                         const CFX_Matrix* pObject2Device,
                                         const CFX_GraphStateData* pGraphState,
                                         uint32_t fill_color,
                                         uint32_t stroke_color,
                                         int fill_mode,
                                         BlendMode blend_type) {
  uint8_t stroke_alpha = pGraphState ? FXARGB_A(stroke_color) : 0;
  uint8_t fill_alpha = (fill_mode & 3) ? FXARGB_A(fill_color) : 0;
  const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints();
  if (stroke_alpha == 0 && pPoints.size() == 2) {
    CFX_PointF pos1 = pPoints[0].m_Point;
    CFX_PointF pos2 = pPoints[1].m_Point;
    if (pObject2Device) {
      pos1 = pObject2Device->Transform(pos1);
      pos2 = pObject2Device->Transform(pos2);
    }
    DrawCosmeticLine(pos1, pos2, fill_color, fill_mode, blend_type);
    return true;
  }

  if ((pPoints.size() == 5 || pPoints.size() == 4) && stroke_alpha == 0) {
    CFX_FloatRect rect_f;
    if (!(fill_mode & FXFILL_RECT_AA) &&
        pPathData->IsRect(pObject2Device, &rect_f)) {
      FX_RECT rect_i = rect_f.GetOuterRect();

      // Depending on the top/bottom, left/right values of the rect it's
      // possible to overflow the Width() and Height() calculations. Check that
      // the rect will have valid dimension before continuing.
      if (!rect_i.Valid())
        return false;

      int width = static_cast<int>(ceil(rect_f.right - rect_f.left));
      if (width < 1) {
        width = 1;
        if (rect_i.left == rect_i.right)
          ++rect_i.right;
      }
      int height = static_cast<int>(ceil(rect_f.top - rect_f.bottom));
      if (height < 1) {
        height = 1;
        if (rect_i.bottom == rect_i.top)
          ++rect_i.bottom;
      }
      if (rect_i.Width() >= width + 1) {
        if (rect_f.left - static_cast<float>(rect_i.left) >
            static_cast<float>(rect_i.right) - rect_f.right) {
          ++rect_i.left;
        } else {
          --rect_i.right;
        }
      }
      if (rect_i.Height() >= height + 1) {
        if (rect_f.top - static_cast<float>(rect_i.top) >
            static_cast<float>(rect_i.bottom) - rect_f.bottom) {
          ++rect_i.top;
        } else {
          --rect_i.bottom;
        }
      }
      if (FillRectWithBlend(rect_i, fill_color, blend_type))
        return true;
    }
  }
  if ((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) &&
      !(fill_mode & FX_FILL_TEXT_MODE)) {
    CFX_PathData newPath;
    bool bThin = false;
    bool setIdentity = false;
    if (pPathData->GetZeroAreaPath(pObject2Device,
                                   !!m_pDeviceDriver->GetDriverType(), &newPath,
                                   &bThin, &setIdentity)) {
      CFX_GraphStateData graphState;
      graphState.m_LineWidth = 0.0f;

      uint32_t strokecolor = fill_color;
      if (bThin)
        strokecolor = (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff));

      const CFX_Matrix* pMatrix = nullptr;
      if (pObject2Device && !pObject2Device->IsIdentity() && !setIdentity)
        pMatrix = pObject2Device;

      int smooth_path = FX_ZEROAREA_FILL;
      if (fill_mode & FXFILL_NOPATHSMOOTH)
        smooth_path |= FXFILL_NOPATHSMOOTH;

      m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor,
                                smooth_path, blend_type);
    }
Ejemplo n.º 4
0
FX_BOOL CGdiPrinterDriver::StretchDIBits(const CFX_DIBSource* pSource,
                                         FX_DWORD color,
                                         int dest_left,
                                         int dest_top,
                                         int dest_width,
                                         int dest_height,
                                         const FX_RECT* pClipRect,
                                         FX_DWORD flags,
                                         int alpha_flag,
                                         void* pIccTransform,
                                         int blend_type) {
  if (pSource->IsAlphaMask()) {
    int alpha = FXGETFLAG_COLORTYPE(alpha_flag)
                    ? FXGETFLAG_ALPHA_FILL(alpha_flag)
                    : FXARGB_A(color);
    if (pSource->GetBPP() != 1 || alpha != 255 || !m_bSupportROP) {
      return FALSE;
    }
    if (dest_width < 0 || dest_height < 0) {
      CFX_DIBitmap* pFlipped =
          pSource->FlipImage(dest_width < 0, dest_height < 0);
      if (pFlipped == NULL) {
        return FALSE;
      }
      if (dest_width < 0) {
        dest_left += dest_width;
      }
      if (dest_height < 0) {
        dest_top += dest_height;
      }
      FX_BOOL ret = GDI_StretchBitMask(pFlipped, dest_left, dest_top,
                                       abs(dest_width), abs(dest_height), color,
                                       flags, alpha_flag, pIccTransform);
      delete pFlipped;
      return ret;
    }
    CFX_DIBExtractor temp(pSource);
    CFX_DIBitmap* pBitmap = temp;
    if (pBitmap == NULL) {
      return FALSE;
    }
    return GDI_StretchBitMask(pBitmap, dest_left, dest_top, dest_width,
                              dest_height, color, flags, alpha_flag,
                              pIccTransform);
  }
  if (pSource->HasAlpha()) {
    return FALSE;
  }
  if (dest_width < 0 || dest_height < 0) {
    CFX_DIBitmap* pFlipped =
        pSource->FlipImage(dest_width < 0, dest_height < 0);
    if (pFlipped == NULL) {
      return FALSE;
    }
    if (dest_width < 0) {
      dest_left += dest_width;
    }
    if (dest_height < 0) {
      dest_top += dest_height;
    }
    FX_BOOL ret =
        GDI_StretchDIBits(pFlipped, dest_left, dest_top, abs(dest_width),
                          abs(dest_height), flags, pIccTransform);
    delete pFlipped;
    return ret;
  }
  CFX_DIBExtractor temp(pSource);
  CFX_DIBitmap* pBitmap = temp;
  if (pBitmap == NULL) {
    return FALSE;
  }
  return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width,
                           dest_height, flags, pIccTransform);
}
Ejemplo n.º 5
0
bool CFX_RenderDevice::DrawPathWithBlend(const CFX_PathData* pPathData,
                                         const CFX_Matrix* pObject2Device,
                                         const CFX_GraphStateData* pGraphState,
                                         uint32_t fill_color,
                                         uint32_t stroke_color,
                                         int fill_mode,
                                         int blend_type) {
  uint8_t stroke_alpha = pGraphState ? FXARGB_A(stroke_color) : 0;
  uint8_t fill_alpha = (fill_mode & 3) ? FXARGB_A(fill_color) : 0;
  if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) {
    FX_PATHPOINT* pPoints = pPathData->GetPoints();
    FX_FLOAT x1, x2, y1, y2;
    if (pObject2Device) {
      pObject2Device->Transform(pPoints[0].m_PointX, pPoints[0].m_PointY, x1,
                                y1);
      pObject2Device->Transform(pPoints[1].m_PointX, pPoints[1].m_PointY, x2,
                                y2);
    } else {
      x1 = pPoints[0].m_PointX;
      y1 = pPoints[0].m_PointY;
      x2 = pPoints[1].m_PointX;
      y2 = pPoints[1].m_PointY;
    }
    DrawCosmeticLine(x1, y1, x2, y2, fill_color, fill_mode, blend_type);
    return true;
  }
  if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) &&
      stroke_alpha == 0) {
    CFX_FloatRect rect_f;
    if (!(fill_mode & FXFILL_RECT_AA) &&
        pPathData->IsRect(pObject2Device, &rect_f)) {
      FX_RECT rect_i = rect_f.GetOuterRect();

      // Depending on the top/bottom, left/right values of the rect it's
      // possible to overflow the Width() and Height() calculations. Check that
      // the rect will have valid dimension before continuing.
      if (!rect_i.Valid())
        return false;

      int width = (int)FXSYS_ceil(rect_f.right - rect_f.left);
      if (width < 1) {
        width = 1;
        if (rect_i.left == rect_i.right)
          rect_i.right++;
      }
      int height = (int)FXSYS_ceil(rect_f.top - rect_f.bottom);
      if (height < 1) {
        height = 1;
        if (rect_i.bottom == rect_i.top)
          rect_i.bottom++;
      }
      if (rect_i.Width() >= width + 1) {
        if (rect_f.left - (FX_FLOAT)(rect_i.left) >
            (FX_FLOAT)(rect_i.right) - rect_f.right) {
          rect_i.left++;
        } else {
          rect_i.right--;
        }
      }
      if (rect_i.Height() >= height + 1) {
        if (rect_f.top - (FX_FLOAT)(rect_i.top) >
            (FX_FLOAT)(rect_i.bottom) - rect_f.bottom) {
          rect_i.top++;
        } else {
          rect_i.bottom--;
        }
      }
      if (FillRectWithBlend(&rect_i, fill_color, blend_type))
        return true;
    }
  }
  if ((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) &&
      !(fill_mode & FX_FILL_TEXT_MODE)) {
    CFX_PathData newPath;
    bool bThin = false;
    if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin,
                                   !!m_pDeviceDriver->GetDriverType())) {
      CFX_GraphStateData graphState;
      graphState.m_LineWidth = 0.0f;
      uint32_t strokecolor = fill_color;
      if (bThin)
        strokecolor = (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff));
      CFX_Matrix* pMatrix = nullptr;
      if (pObject2Device && !pObject2Device->IsIdentity())
        pMatrix = (CFX_Matrix*)pObject2Device;
      int smooth_path = FX_ZEROAREA_FILL;
      if (fill_mode & FXFILL_NOPATHSMOOTH)
        smooth_path |= FXFILL_NOPATHSMOOTH;
      m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor,
                                smooth_path, blend_type);
    }
Ejemplo n.º 6
0
FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource*      pBitmap,
        FX_ARGB                     argb,
        int                         dest_left,
        int                         dest_top,
        int                         dest_width,
        int                         dest_height,
        const FX_RECT*              clipRect,
        FX_DWORD                    flags,
        int                         alphaFlag	   ,
        void*                       iccTransform ,
        int							blend_type)
{
    SaveState();
    if (clipRect) {
        CGContextBeginPath(_context);
        CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height());
        rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User);
        CGContextAddRect(_context, rect_clip);
        CGContextClip(_context);
    }
    CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height);
    rect = CGRectApplyAffineTransform(rect, _foxitDevice2User);
    if (FXDIB_BICUBIC_INTERPOL == flags) {
        CGContextSetInterpolationQuality(_context, kCGInterpolationHigh);
    } else if (FXDIB_DOWNSAMPLE == flags) {
        CGContextSetInterpolationQuality(_context, kCGInterpolationNone);
    } else {
        CGContextSetInterpolationQuality(_context, kCGInterpolationMedium);
    }
    CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height);
    CFX_DIBitmap* pBitmap1 = NULL;
    if (pBitmap->IsAlphaMask()) {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
        if (NULL == pBitmap1) {
            RestoreState(FALSE);
            return FALSE;
        }
        CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
                                            pBitmap1->GetBuffer(),
                                            pBitmap1->GetPitch() * pBitmap1->GetHeight(),
                                            NULL);
        CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
        CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
        CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
                                          pBitmap1->GetHeight(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetPitch(),
                                          pColorSpace,
                                          bitmapInfo,
                                          pBitmapProvider, NULL, true,
                                          kCGRenderingIntentDefault);
        CGContextClipToMask(_context, rect, pImage);
        CGContextSetRGBFillColor(_context,
                                 FXARGB_R(argb) / 255.f,
                                 FXARGB_G(argb) / 255.f,
                                 FXARGB_B(argb) / 255.f,
                                 FXARGB_A(argb) / 255.f);
        CGContextFillRect(_context, rect);
        CGImageRelease(pImage);
        CGColorSpaceRelease(pColorSpace);
        CGDataProviderRelease(pBitmapProvider);
        if (pBitmap1 != pBitmap) {
            delete pBitmap1;
        }
        RestoreState(FALSE);
        return TRUE;
    }
    if (pBitmap->GetBPP() < 32) {
        pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
    } else {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
    }
    if (NULL == pBitmap1) {
        RestoreState(FALSE);
        return FALSE;
    }
    if (pBitmap1->HasAlpha()) {
        if (pBitmap1 == pBitmap) {
            pBitmap1 = pBitmap->Clone();
            if (!pBitmap1) {
                RestoreState(FALSE);
                return FALSE;
            }
        }
        for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
            FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
            for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
                pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
                pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
                pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
                pScanline += 4;
            }
        }
    }
    CGContextRef ctx = createContextWithBitmap(pBitmap1);
    CGImageRef image = CGBitmapContextCreateImage(ctx);
    CGContextDrawImage(_context, rect, image);
    CGImageRelease(image);
    CGContextRelease(ctx);
    if (pBitmap1 != pBitmap) {
        delete pBitmap1;
    }
    RestoreState(FALSE);
    return TRUE;
}
Ejemplo n.º 7
0
FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource*      pBitmap,
        FX_ARGB                     argb,
        const FX_RECT*              srcRect,
        int                         dest_left,
        int                         dest_top,
        int                         blendType,
        int                         alphaFlag       ,
        void*                       iccTransform    )
{
    SaveState();
    CGFloat src_left, src_top, src_width, src_height;
    if (srcRect) {
        src_left = srcRect->left;
        src_top = srcRect->top;
        src_width = srcRect->Width();
        src_height = srcRect->Height();
    } else {
        src_left = src_top = 0;
        src_width = pBitmap->GetWidth();
        src_height = pBitmap->GetHeight();
    }
    CGAffineTransform ctm = CGContextGetCTM(_context);
    CGFloat scale_x = FXSYS_fabs(ctm.a);
    CGFloat scale_y = FXSYS_fabs(ctm.d);
    src_left /= scale_x;
    src_top /= scale_y;
    src_width /= scale_x;
    src_height /= scale_y;
    CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height);
    CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
    CGContextBeginPath(_context);
    CGContextAddRect(_context, rect_usr);
    CGContextClip(_context);
    rect_usr.size = CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y);
    rect_usr = CGRectOffset(rect_usr, -src_left, -src_top);
    CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr);
    CFX_DIBitmap* pBitmap1 = NULL;
    if (pBitmap->IsAlphaMask()) {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
        if (NULL == pBitmap1) {
            RestoreState(FALSE);
            return FALSE;
        }
        CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
                                            pBitmap1->GetBuffer(),
                                            pBitmap1->GetPitch() * pBitmap1->GetHeight(),
                                            NULL);
        CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
        CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
        CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
                                          pBitmap1->GetHeight(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetPitch(),
                                          pColorSpace,
                                          bitmapInfo,
                                          pBitmapProvider, NULL, true,
                                          kCGRenderingIntentDefault);
        CGContextClipToMask(_context, rect_usr, pImage);
        CGContextSetRGBFillColor(_context,
                                 FXARGB_R(argb) / 255.f,
                                 FXARGB_G(argb) / 255.f,
                                 FXARGB_B(argb) / 255.f,
                                 FXARGB_A(argb) / 255.f);
        CGContextFillRect(_context, rect_usr);
        CGImageRelease(pImage);
        CGColorSpaceRelease(pColorSpace);
        CGDataProviderRelease(pBitmapProvider);
        if (pBitmap1 != pBitmap) {
            delete pBitmap1;
        }
        RestoreState(FALSE);
        return TRUE;
    }
    if (pBitmap->GetBPP() < 32) {
        pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
    } else {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
    }
    if (NULL == pBitmap1) {
        RestoreState(FALSE);
        return FALSE;
    }
    if (pBitmap1->HasAlpha()) {
        if (pBitmap1 == pBitmap) {
            pBitmap1 = pBitmap->Clone();
            if (!pBitmap1) {
                RestoreState(FALSE);
                return FALSE;
            }
        }
        for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
            FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
            for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
                pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
                pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
                pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
                pScanline += 4;
            }
        }
    }
    CGContextRef ctx = createContextWithBitmap(pBitmap1);
    CGImageRef image = CGBitmapContextCreateImage(ctx);
    int blend_mode = blendType;
    if (FXDIB_BLEND_HARDLIGHT == blendType) {
        blend_mode = kCGBlendModeSoftLight;
    } else if (FXDIB_BLEND_SOFTLIGHT == blendType) {
        blend_mode = kCGBlendModeHardLight;
    } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && blendType <= FXDIB_BLEND_LUMINOSITY) {
        blend_mode = blendType - 9;
    } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) {
        blend_mode = kCGBlendModeNormal;
    }
    CGContextSetBlendMode(_context, (CGBlendMode)blend_mode);
    CGContextDrawImage(_context, rect_usr, image);
    CGImageRelease(image);
    CGContextRelease(ctx);
    if (pBitmap1 != pBitmap) {
        delete pBitmap1;
    }
    RestoreState(FALSE);
    return TRUE;
}
Ejemplo n.º 8
0
FX_BOOL CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource, FX_DWORD color,
                                   const CFX_AffineMatrix* pMatrix, FX_DWORD flags,
                                   int alpha_flag, void* pIccTransform)
{
    StartRendering();
    if ((pMatrix->a == 0 && pMatrix->b == 0) || (pMatrix->c == 0 && pMatrix->d == 0)) {
        return TRUE;
    }
    if (pSource->HasAlpha()) {
        return FALSE;
    }
    int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(color) : FXARGB_A(color);
    if (pSource->IsAlphaMask() && (alpha < 255 || pSource->GetBPP() != 1)) {
        return FALSE;
    }
    OUTPUT_PS("q\n");
    CFX_ByteTextBuf buf;
    buf << FX_BSTRC("[") << pMatrix->a << FX_BSTRC(" ") << pMatrix->b << FX_BSTRC(" ") <<
        pMatrix->c << FX_BSTRC(" ") << pMatrix->d << FX_BSTRC(" ") << pMatrix->e <<
        FX_BSTRC(" ") << pMatrix->f << FX_BSTRC("]cm ");
    int width = pSource->GetWidth();
    int height = pSource->GetHeight();
    buf << width << FX_BSTRC(" ") << height;
    if (pSource->GetBPP() == 1 && pSource->GetPalette() == NULL) {
        int pitch = (width + 7) / 8;
        FX_DWORD src_size = height * pitch;
        FX_LPBYTE src_buf = FX_Alloc(FX_BYTE, src_size);
        if (!src_buf) {
            return FALSE;
        }
        for (int row = 0; row < height; row ++) {
            FX_LPCBYTE src_scan = pSource->GetScanline(row);
            FXSYS_memcpy32(src_buf + row * pitch, src_scan, pitch);
        }
        FX_LPBYTE output_buf;
        FX_DWORD output_size;
        FaxCompressData(src_buf, width, height, output_buf, output_size);
        if (pSource->IsAlphaMask()) {
            SetColor(color, alpha_flag, pIccTransform);
            m_bColorSet = FALSE;
            buf << FX_BSTRC(" true[");
        } else {
            buf << FX_BSTRC(" 1[");
        }
        buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height <<
            FX_BSTRC("]currentfile/ASCII85Decode filter ");
        if (output_buf != src_buf)
            buf << FX_BSTRC("<</K -1/EndOfBlock false/Columns ") << width << FX_BSTRC("/Rows ") << height <<
                FX_BSTRC(">>/CCITTFaxDecode filter ");
        if (pSource->IsAlphaMask()) {
            buf << FX_BSTRC("iM\n");
        } else {
            buf << FX_BSTRC("false 1 colorimage\n");
        }
        m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
        WritePSBinary(output_buf, output_size);
        FX_Free(output_buf);
    } else {
        CFX_DIBSource* pConverted = (CFX_DIBSource*)pSource;
        if (pIccTransform) {
            FXDIB_Format format = m_bCmykOutput ? FXDIB_Cmyk : FXDIB_Rgb;
            pConverted = pSource->CloneConvert(format, NULL, pIccTransform);
        } else {
            switch (pSource->GetFormat()) {
                case FXDIB_1bppRgb:
                case FXDIB_Rgb32:
                    pConverted = pSource->CloneConvert(FXDIB_Rgb);
                    break;
                case FXDIB_8bppRgb:
                    if (pSource->GetPalette() != NULL) {
                        pConverted = pSource->CloneConvert(FXDIB_Rgb);
                    }
                    break;
                case FXDIB_1bppCmyk:
                    pConverted = pSource->CloneConvert(FXDIB_Cmyk);
                    break;
                case FXDIB_8bppCmyk:
                    if (pSource->GetPalette() != NULL) {
                        pConverted = pSource->CloneConvert(FXDIB_Cmyk);
                    }
                    break;
                default:
                    break;
            }
        }
        if (pConverted == NULL) {
            OUTPUT_PS("\nQ\n");
            return FALSE;
        }
        int Bpp = pConverted->GetBPP() / 8;
        FX_LPBYTE output_buf = NULL;
        FX_STRSIZE output_size = 0;
        FX_LPCSTR filter = NULL;
        if (flags & FXRENDER_IMAGE_LOSSY) {
            CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
            if (pEncoders && pEncoders->GetJpegModule()->Encode(pConverted, output_buf, output_size)) {
                filter = "/DCTDecode filter ";
            }
        }
        if (filter == NULL) {
            int src_pitch = width * Bpp;
            output_size = height * src_pitch;
            output_buf = FX_Alloc(FX_BYTE, output_size);
            if (!output_buf) {
                if (pConverted != pSource) {
                    delete pConverted;
                    pConverted = NULL;
                }
                return FALSE;
            }
            for (int row = 0; row < height; row ++) {
                FX_LPCBYTE src_scan = pConverted->GetScanline(row);
                FX_LPBYTE dest_scan = output_buf + row * src_pitch;
                if (Bpp == 3) {
                    for (int col = 0; col < width; col ++) {
                        *dest_scan++ = src_scan[2];
                        *dest_scan++ = src_scan[1];
                        *dest_scan++ = *src_scan;
                        src_scan += 3;
                    }
                } else {
                    FXSYS_memcpy32(dest_scan, src_scan, src_pitch);
                }
            }
            FX_LPBYTE compressed_buf;
            FX_DWORD compressed_size;
            PSCompressData(m_PSLevel, output_buf, output_size, compressed_buf, compressed_size, filter);
            if (output_buf != compressed_buf) {
                FX_Free(output_buf);
            }
            output_buf = compressed_buf;
            output_size = compressed_size;
        }
        if (pConverted != pSource) {
            delete pConverted;
            pConverted = NULL;
        }
        buf << FX_BSTRC(" 8[");
        buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height << FX_BSTRC("]");
        buf << FX_BSTRC("currentfile/ASCII85Decode filter ");
        if (filter) {
            buf << filter;
        }
        buf << FX_BSTRC("false ") << Bpp;
        buf << FX_BSTRC(" colorimage\n");
        m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
        WritePSBinary(output_buf, output_size);
        FX_Free(output_buf);
    }
    OUTPUT_PS("\nQ\n");
    return TRUE;
}
Ejemplo n.º 9
0
FX_BOOL CFX_PSRenderer::DrawPath(const CFX_PathData* pPathData,
                                 const CFX_AffineMatrix* pObject2Device,
                                 const CFX_GraphStateData* pGraphState,
                                 FX_DWORD fill_color,
                                 FX_DWORD stroke_color,
                                 int fill_mode,
                                 int alpha_flag,
                                 void* pIccTransform
                                )
{
    StartRendering();
    int fill_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(fill_color);
    int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_STROKE(alpha_flag) : FXARGB_A(stroke_color);
    if (fill_alpha && fill_alpha < 255) {
        return FALSE;
    }
    if (stroke_alpha && stroke_alpha < 255) {
        return FALSE;
    }
    if (fill_alpha == 0 && stroke_alpha == 0) {
        return FALSE;
    }
    if (stroke_alpha) {
        SetGraphState(pGraphState);
        if (pObject2Device) {
            CFX_ByteTextBuf buf;
            buf << FX_BSTRC("mx Cm [") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ") <<
                pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d << FX_BSTRC(" ") << pObject2Device->e <<
                FX_BSTRC(" ") << pObject2Device->f << FX_BSTRC("]cm ");
            m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
        }
    }
    OutputPath(pPathData, stroke_alpha ? NULL : pObject2Device);
    if (fill_mode && fill_alpha) {
        SetColor(fill_color, alpha_flag, pIccTransform);
        if ((fill_mode & 3) == FXFILL_WINDING) {
            if (stroke_alpha) {
                OUTPUT_PS("q f Q ");
            } else {
                OUTPUT_PS("f");
            }
        } else if ((fill_mode & 3) == FXFILL_ALTERNATE) {
            if (stroke_alpha) {
                OUTPUT_PS("q F Q ");
            } else {
                OUTPUT_PS("F");
            }
        }
    }
    if (stroke_alpha) {
        SetColor(stroke_color, alpha_flag, pIccTransform);
        if (pObject2Device) {
            OUTPUT_PS("s sm");
        } else {
            OUTPUT_PS("s");
        }
    }
    OUTPUT_PS("\n");
    return TRUE;
}