diff options
Diffstat (limited to 'core/fxge/apple')
-rw-r--r-- | core/fxge/apple/apple_int.h | 104 | ||||
-rw-r--r-- | core/fxge/apple/cfx_quartzdevice.h | 31 | ||||
-rw-r--r-- | core/fxge/apple/fx_apple_platform.cpp | 5 | ||||
-rw-r--r-- | core/fxge/apple/fx_mac_imp.cpp | 4 | ||||
-rw-r--r-- | core/fxge/apple/fx_quartz_device.cpp | 949 |
5 files changed, 13 insertions, 1080 deletions
diff --git a/core/fxge/apple/apple_int.h b/core/fxge/apple/apple_int.h index 9881e17a88..fed6abcfb0 100644 --- a/core/fxge/apple/apple_int.h +++ b/core/fxge/apple/apple_int.h @@ -9,17 +9,13 @@ #include "core/fxcrt/fx_system.h" -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - #include "core/fxge/cfx_graphstatedata.h" #include "core/fxge/cfx_pathdata.h" #include "core/fxge/cfx_renderdevice.h" #include "core/fxge/fx_dib.h" #include "core/fxge/ifx_renderdevicedriver.h" -#if _FX_OS_ == _FX_MACOSX_ #include <Carbon/Carbon.h> -#endif class CQuartz2D { public: @@ -49,104 +45,4 @@ class CApplePlatform { CQuartz2D m_quartz2d; }; -class CFX_QuartzDeviceDriver : public IFX_RenderDeviceDriver { - public: - CFX_QuartzDeviceDriver(CGContextRef context, int32_t deviceClass); - ~CFX_QuartzDeviceDriver() override; - - // IFX_RenderDeviceDriver - int GetDeviceCaps(int caps_id) const override; - CFX_Matrix GetCTM() const override; - void SaveState() override; - void RestoreState(bool bKeepSaved) override; - bool SetClip_PathFill(const CFX_PathData* pPathData, - const CFX_Matrix* pObject2Device, - int fill_mode) override; - bool SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_Matrix* pObject2Device, - const CFX_GraphStateData* pGraphState) override; - bool DrawPath(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) override; - bool FillRectWithBlend(const FX_RECT* pRect, - uint32_t fill_color, - int blend_type) override; - bool DrawCosmeticLine(FX_FLOAT x1, - FX_FLOAT y1, - FX_FLOAT x2, - FX_FLOAT y2, - uint32_t color, - int blend_type) override; - bool GetClipBox(FX_RECT* pRect) override; - bool GetDIBits(CFX_DIBitmap* pBitmap, int left, int top) override; - bool SetDIBits(const CFX_DIBSource* pBitmap, - uint32_t color, - const FX_RECT* pSrcRect, - int dest_left, - int dest_top, - int blend_type) override; - bool StretchDIBits(const CFX_DIBSource* pBitmap, - uint32_t color, - int dest_left, - int dest_top, - int dest_width, - int dest_height, - const FX_RECT* pClipRect, - uint32_t flags, - int blend_type) override; - bool StartDIBits(const CFX_DIBSource* pBitmap, - int bitmap_alpha, - uint32_t color, - const CFX_Matrix* pMatrix, - uint32_t flags, - void*& handle, - int blend_type) override; - bool DrawDeviceText(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - const CFX_Matrix* pObject2Device, - FX_FLOAT font_size, - uint32_t color) override; - void ClearDriver() override; - - protected: - void setStrokeInfo(const CFX_GraphStateData* graphState, - FX_ARGB argb, - FX_FLOAT lineWidth); - void setFillInfo(FX_ARGB argb); - void setPathToContext(const CFX_PathData* pathData); - FX_FLOAT getLineWidth(const CFX_GraphStateData* graphState, - CGAffineTransform ctm); - bool CG_DrawGlyphRun(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - const CFX_Matrix* pGlyphMatrix, - const CFX_Matrix* pObject2Device, - FX_FLOAT font_size, - uint32_t argb); - void CG_SetImageTransform(int dest_left, - int dest_top, - int dest_width, - int dest_height, - CGRect* rect); - - CGContextRef m_context; - CGAffineTransform m_foxitDevice2User; - CGAffineTransform m_user2FoxitDevice; - int32_t m_saveCount; - - int32_t m_width; - int32_t m_height; - int32_t m_bitsPerPixel; - int32_t m_deviceClass; - int32_t m_renderCaps; - int32_t m_horzSize; - int32_t m_vertSize; -}; -#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - #endif // CORE_FXGE_APPLE_APPLE_INT_H_ diff --git a/core/fxge/apple/cfx_quartzdevice.h b/core/fxge/apple/cfx_quartzdevice.h deleted file mode 100644 index 310cef8463..0000000000 --- a/core/fxge/apple/cfx_quartzdevice.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FXGE_APPLE_CFX_QUARTZDEVICE_H_ -#define CORE_FXGE_APPLE_CFX_QUARTZDEVICE_H_ - -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - -#include "core/fxge/cfx_renderdevice.h" - -class CFX_QuartzDevice : public CFX_RenderDevice { - public: - CFX_QuartzDevice(); - ~CFX_QuartzDevice() override; - - bool Attach(CGContextRef context, int32_t nDeviceClass = FXDC_DISPLAY); - bool Attach(CFX_DIBitmap* pBitmap); - bool Create(int32_t width, int32_t height, FXDIB_Format format); - - CGContextRef GetContext(); - - protected: - CGContextRef m_pContext; - bool m_bOwnedBitmap; -}; -#endif - -#endif // CORE_FXGE_APPLE_CFX_QUARTZDEVICE_H_ diff --git a/core/fxge/apple/fx_apple_platform.cpp b/core/fxge/apple/fx_apple_platform.cpp index 403ed4a12e..7fc12fd362 100644 --- a/core/fxge/apple/fx_apple_platform.cpp +++ b/core/fxge/apple/fx_apple_platform.cpp @@ -6,14 +6,11 @@ #include "core/fxcrt/fx_system.h" -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - #ifndef _SKIA_SUPPORT_ #include "core/fxge/agg/fx_agg_driver.h" #endif #include "core/fxge/apple/apple_int.h" -#include "core/fxge/apple/cfx_quartzdevice.h" #include "core/fxge/cfx_facecache.h" #include "core/fxge/cfx_gemodule.h" #include "core/fxge/cfx_renderdevice.h" @@ -186,5 +183,3 @@ void CFX_Font::ReleasePlatformResource() { m_pPlatformFont = nullptr; } } - -#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ diff --git a/core/fxge/apple/fx_mac_imp.cpp b/core/fxge/apple/fx_mac_imp.cpp index fa6572084c..7c3cb04105 100644 --- a/core/fxge/apple/fx_mac_imp.cpp +++ b/core/fxge/apple/fx_mac_imp.cpp @@ -9,8 +9,6 @@ #include "core/fxge/ge/cfx_folderfontinfo.h" #include "core/fxge/ifx_systemfontinfo.h" -#if _FX_OS_ == _FX_MACOSX_ - namespace { const struct { @@ -137,5 +135,3 @@ void CFX_GEModule::DestroyPlatform() { delete reinterpret_cast<CApplePlatform*>(m_pPlatformData); m_pPlatformData = nullptr; } - -#endif // _FX_OS_ == _FX_MACOSX_ diff --git a/core/fxge/apple/fx_quartz_device.cpp b/core/fxge/apple/fx_quartz_device.cpp index 112399d17f..35e9a74124 100644 --- a/core/fxge/apple/fx_quartz_device.cpp +++ b/core/fxge/apple/fx_quartz_device.cpp @@ -20,17 +20,14 @@ #include "core/fxge/ge/fx_text_int.h" #include "third_party/base/ptr_util.h" -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ #include "core/fxge/apple/apple_int.h" -#include "core/fxge/apple/cfx_quartzdevice.h" #ifndef CGFLOAT_IS_DOUBLE #error Expected CGFLOAT_IS_DOUBLE to be defined by CoreGraphics headers #endif void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap) { - if (!pBitmap) { + if (!pBitmap) return nullptr; - } CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little; switch (pBitmap->GetFormat()) { case FXDIB_Rgb32: @@ -47,11 +44,12 @@ void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap) { CGColorSpaceRelease(colorSpace); return context; } + void CQuartz2D::destroyGraphics(void* graphics) { - if (graphics) { + if (graphics) CGContextRelease((CGContextRef)graphics); - } } + void* CQuartz2D::CreateFont(const uint8_t* pFontData, uint32_t dwFontSize) { CGDataProviderRef pDataProvider = CGDataProviderCreateWithData( nullptr, pFontData, (size_t)dwFontSize, nullptr); @@ -62,19 +60,21 @@ void* CQuartz2D::CreateFont(const uint8_t* pFontData, uint32_t dwFontSize) { CGDataProviderRelease(pDataProvider); return pCGFont; } + void CQuartz2D::DestroyFont(void* pFont) { CGFontRelease((CGFontRef)pFont); } + void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_Matrix* matrix) { - if (!graphics || !matrix) { + if (!graphics || !matrix) return; - } CGContextRef context = (CGContextRef)graphics; CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f; CGContextSetTextMatrix( context, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, ty)); } + bool CQuartz2D::drawGraphicsString(void* graphics, void* font, FX_FLOAT fontSize, @@ -83,9 +83,8 @@ bool CQuartz2D::drawGraphicsString(void* graphics, int32_t charsCount, FX_ARGB argb, CFX_Matrix* matrix) { - if (!graphics) { + if (!graphics) return false; - } CGContextRef context = (CGContextRef)graphics; CGContextSetFont(context, (CGFontRef)font); CGContextSetFontSize(context, fontSize); @@ -117,935 +116,13 @@ bool CQuartz2D::drawGraphicsString(void* graphics, CGContextRestoreGState(context); return true; } + void CQuartz2D::saveGraphicsState(void* graphics) { - if (graphics) { + if (graphics) CGContextSaveGState((CGContextRef)graphics); - } } + void CQuartz2D::restoreGraphicsState(void* graphics) { - if (graphics) { + if (graphics) CGContextRestoreGState((CGContextRef)graphics); - } -} -static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap) { - if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) { - return nullptr; - } - CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little; - if (pBitmap->HasAlpha()) { - bitmapInfo |= kCGImageAlphaPremultipliedFirst; - } else { - bitmapInfo |= kCGImageAlphaNoneSkipFirst; - } - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef context = CGBitmapContextCreate( - pBitmap->GetBuffer(), pBitmap->GetWidth(), pBitmap->GetHeight(), 8, - pBitmap->GetPitch(), colorSpace, bitmapInfo); - CGColorSpaceRelease(colorSpace); - return context; -} -CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context, - int32_t deviceClass) { - m_saveCount = 0; - m_context = context; - m_deviceClass = deviceClass; - CGContextRetain(m_context); - CGRect r = CGContextGetClipBoundingBox(context); - m_width = FXSYS_round(r.size.width); - m_height = FXSYS_round(r.size.height); - m_renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | FXRC_ALPHA_PATH | - FXRC_ALPHA_IMAGE | FXRC_BIT_MASK | FXRC_ALPHA_MASK; - if (m_deviceClass != FXDC_DISPLAY) { - } else { - CGImageRef image = CGBitmapContextCreateImage(m_context); - if (image) { - m_renderCaps |= FXRC_GET_BITS; - m_width = CGImageGetWidth(image); - m_height = CGImageGetHeight(image); - CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image); - if (kCGImageAlphaPremultipliedFirst == alphaInfo || - kCGImageAlphaPremultipliedLast == alphaInfo || - kCGImageAlphaOnly == alphaInfo) { - m_renderCaps |= FXRC_ALPHA_OUTPUT; - } - } - CGImageRelease(image); - } - CGAffineTransform ctm = CGContextGetCTM(m_context); - CGContextSaveGState(m_context); - m_saveCount++; - if (ctm.d >= 0) { - CGFloat offset_x, offset_y; - offset_x = ctm.tx; - offset_y = ctm.ty; - CGContextTranslateCTM(m_context, -offset_x, -offset_y); - CGContextConcatCTM(m_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, - m_height + offset_y)); - } - m_foxitDevice2User = CGAffineTransformIdentity; - m_user2FoxitDevice = CGAffineTransformInvert(m_foxitDevice2User); -} -CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver() { - CGContextRestoreGState(m_context); - m_saveCount--; - for (int i = 0; i < m_saveCount; ++i) { - CGContextRestoreGState(m_context); - } - if (m_context) { - CGContextRelease(m_context); - } -} -int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID) const { - switch (capsID) { - case FXDC_DEVICE_CLASS: - return m_deviceClass; - case FXDC_PIXEL_WIDTH: - return m_width; - case FXDC_PIXEL_HEIGHT: - return m_height; - case FXDC_BITS_PIXEL: - return 32; - case FXDC_RENDER_CAPS: - return m_renderCaps; - default: - return 0; - } -} -CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const { - CGAffineTransform ctm = CGContextGetCTM(m_context); - return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty); -} -void CFX_QuartzDeviceDriver::SaveState() { - CGContextSaveGState(m_context); - m_saveCount++; -} - -void CFX_QuartzDeviceDriver::RestoreState(bool isKeepSaved) { - CGContextRestoreGState(m_context); - if (isKeepSaved) { - CGContextSaveGState(m_context); - } else { - m_saveCount--; - } -} - -bool CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData, - const CFX_Matrix* matrix, - int fillMode) { - SaveState(); - CGAffineTransform m = CGAffineTransformIdentity; - if (matrix) { - m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), - matrix->GetD(), matrix->GetE(), matrix->GetF()); - } - m = CGAffineTransformConcat(m, m_foxitDevice2User); - CGContextConcatCTM(m_context, m); - setPathToContext(pathData); - RestoreState(false); - if ((fillMode & 3) == FXFILL_WINDING) { - CGContextClip(m_context); - } else { - CGContextEOClip(m_context); - } - return true; -} -FX_FLOAT CFX_QuartzDeviceDriver::getLineWidth( - const CFX_GraphStateData* graphState, - CGAffineTransform ctm) { - FX_FLOAT lineWidth = graphState->m_LineWidth; - if (graphState->m_LineWidth <= 0.f) { - CGSize size; - size.width = 1; - size.height = 1; - CGSize temp = CGSizeApplyAffineTransform(size, ctm); - CGFloat x = 1 / temp.width; - CGFloat y = 1 / temp.height; - lineWidth = x > y ? x : y; - } - return lineWidth; -} -bool CFX_QuartzDeviceDriver::SetClip_PathStroke( - const CFX_PathData* pathData, - const CFX_Matrix* matrix, - const CFX_GraphStateData* graphState) { - SaveState(); - CGAffineTransform m = CGAffineTransformIdentity; - if (matrix) { - m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), - matrix->GetD(), matrix->GetE(), matrix->GetF()); - } - m = CGAffineTransformConcat(m, m_foxitDevice2User); - CGContextConcatCTM(m_context, m); - FX_FLOAT lineWidth = getLineWidth(graphState, m); - setStrokeInfo(graphState, 0xFF000000, lineWidth); - setPathToContext(pathData); - CGContextReplacePathWithStrokedPath(m_context); - RestoreState(false); - CGContextClip(m_context); - return true; -} -static CGBlendMode GetCGBlendMode(int blend_type) { - CGBlendMode mode = kCGBlendModeNormal; - switch (blend_type) { - case FXDIB_BLEND_NORMAL: - mode = kCGBlendModeNormal; - break; - case FXDIB_BLEND_MULTIPLY: - mode = kCGBlendModeMultiply; - break; - case FXDIB_BLEND_SCREEN: - mode = kCGBlendModeScreen; - break; - case FXDIB_BLEND_OVERLAY: - mode = kCGBlendModeOverlay; - break; - case FXDIB_BLEND_DARKEN: - mode = kCGBlendModeDarken; - break; - case FXDIB_BLEND_LIGHTEN: - mode = kCGBlendModeLighten; - break; - case FXDIB_BLEND_COLORDODGE: - mode = kCGBlendModeColorDodge; - break; - case FXDIB_BLEND_COLORBURN: - mode = kCGBlendModeColorBurn; - break; - case FXDIB_BLEND_HARDLIGHT: - mode = kCGBlendModeHardLight; - break; - case FXDIB_BLEND_SOFTLIGHT: - mode = kCGBlendModeSoftLight; - break; - case FXDIB_BLEND_DIFFERENCE: - mode = kCGBlendModeDifference; - break; - case FXDIB_BLEND_EXCLUSION: - mode = kCGBlendModeExclusion; - break; - case FXDIB_BLEND_HUE: - mode = kCGBlendModeHue; - break; - case FXDIB_BLEND_SATURATION: - mode = kCGBlendModeSaturation; - break; - case FXDIB_BLEND_COLOR: - mode = kCGBlendModeColor; - break; - case FXDIB_BLEND_LUMINOSITY: - mode = kCGBlendModeLuminosity; - break; - default: - mode = kCGBlendModeNormal; - break; - } - return mode; -} - -bool CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData, - const CFX_Matrix* matrix, - const CFX_GraphStateData* graphState, - uint32_t fillArgb, - uint32_t strokeArgb, - int fillMode, - int blend_type) { - SaveState(); - CGBlendMode mode = GetCGBlendMode(blend_type); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(m_context, mode); - } - CGAffineTransform m = CGAffineTransformIdentity; - if (matrix) { - m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), - matrix->GetD(), matrix->GetE(), matrix->GetF()); - } - m = CGAffineTransformConcat(m, m_foxitDevice2User); - CGContextConcatCTM(m_context, m); - int pathMode = 0; - if (graphState && strokeArgb) { - CGContextSetMiterLimit(m_context, graphState->m_MiterLimit); - FX_FLOAT lineWidth = getLineWidth(graphState, m); - setStrokeInfo(graphState, strokeArgb, lineWidth); - pathMode |= 4; - } - if (fillMode && fillArgb) { - setFillInfo(fillArgb); - if ((fillMode & 3) == FXFILL_WINDING) { - pathMode |= 1; - } else if ((fillMode & 3) == FXFILL_ALTERNATE) { - pathMode |= 2; - } - } - setPathToContext(pathData); - if (fillMode & FXFILL_FULLCOVER) { - CGContextSetShouldAntialias(m_context, false); - } - if (pathMode == 4) { - CGContextStrokePath(m_context); - } else if (pathMode == 1) { - CGContextFillPath(m_context); - } else if (pathMode == 2) { - CGContextEOFillPath(m_context); - } else if (pathMode == 5) { - CGContextDrawPath(m_context, kCGPathFillStroke); - } else if (pathMode == 6) { - CGContextDrawPath(m_context, kCGPathEOFillStroke); - } - RestoreState(false); - return true; -} - -bool CFX_QuartzDeviceDriver::FillRectWithBlend(const FX_RECT* rect, - FX_ARGB fillArgb, - int blend_type) { - CGBlendMode mode = GetCGBlendMode(blend_type); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(m_context, mode); - } - CGRect rect_fx = - CGRectMake(rect->left, rect->top, rect->Width(), rect->Height()); - CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, m_foxitDevice2User); - int32_t a, r, g, b; - ArgbDecode(fillArgb, a, r, g, b); - CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f, - a / 255.f); - CGContextFillRect(m_context, rect_usr); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(m_context, kCGBlendModeNormal); - } - return true; -} - -bool CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, - FX_FLOAT y1, - FX_FLOAT x2, - FX_FLOAT y2, - uint32_t argb, - int blend_type) { - CGBlendMode mode = GetCGBlendMode(blend_type); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(m_context, mode); - } - CGPoint pt = - CGPointApplyAffineTransform(CGPointMake(x1, y1), m_foxitDevice2User); - x1 = pt.x; - y1 = pt.y; - pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), m_foxitDevice2User); - x2 = pt.x; - y2 = pt.y; - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBStrokeColor(m_context, r / 255.f, g / 255.f, b / 255.f, - a / 255.f); - CGContextMoveToPoint(m_context, x1, y1); - CGContextAddLineToPoint(m_context, x2, y2); - CGContextStrokePath(m_context); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(m_context, kCGBlendModeNormal); - } - return true; -} - -bool CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) { - CGRect r = CGContextGetClipBoundingBox(m_context); - r = CGRectApplyAffineTransform(r, m_user2FoxitDevice); - rect->left = FXSYS_floor(r.origin.x); - rect->top = FXSYS_floor(r.origin.y); - rect->right = FXSYS_ceil(r.origin.x + r.size.width); - rect->bottom = FXSYS_ceil(r.origin.y + r.size.height); - return true; -} - -bool CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap, - int32_t left, - int32_t top) { - if (FXDC_PRINTER == m_deviceClass || bitmap->GetBPP() < 32 || - !(m_renderCaps | FXRC_GET_BITS)) { - return false; - } - - CGPoint pt = CGPointMake(left, top); - pt = CGPointApplyAffineTransform(pt, m_foxitDevice2User); - CGAffineTransform ctm = CGContextGetCTM(m_context); - pt.x *= FXSYS_fabs(ctm.a); - pt.y *= FXSYS_fabs(ctm.d); - CGImageRef image = CGBitmapContextCreateImage(m_context); - if (!image) - return false; - - CGFloat width = (CGFloat)bitmap->GetWidth(); - CGFloat height = (CGFloat)bitmap->GetHeight(); - if (width + pt.x > m_width) - width -= (width + pt.x - m_width); - if (height + pt.y > m_height) - height -= (height + pt.y - m_height); - - CGImageRef subImage = CGImageCreateWithImageInRect( - image, CGRectMake(pt.x, pt.y, width, height)); - CGContextRef context = createContextWithBitmap(bitmap); - CGRect rect = CGContextGetClipBoundingBox(context); - CGContextClearRect(context, rect); - CGContextDrawImage(context, rect, subImage); - CGContextRelease(context); - CGImageRelease(subImage); - CGImageRelease(image); - if (!bitmap->HasAlpha()) - return true; - - for (int row = 0; row < bitmap->GetHeight(); row++) { - uint8_t* pScanline = (uint8_t*)bitmap->GetScanline(row); - for (int col = 0; col < bitmap->GetWidth(); col++) { - if (pScanline[3] > 0) { - pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f); - pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f); - pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f); - } - pScanline += 4; - } - } - return true; -} - -bool CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, - FX_ARGB argb, - const FX_RECT* srcRect, - int dest_left, - int dest_top, - int blendType) { - 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(m_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, m_foxitDevice2User); - CGContextBeginPath(m_context); - CGContextAddRect(m_context, rect_usr); - CGContextClip(m_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 = nullptr; - if (pBitmap->IsAlphaMask()) { - if (pBitmap->GetBuffer()) { - pBitmap1 = (CFX_DIBitmap*)pBitmap; - } else { - pBitmap1 = pBitmap->Clone(); - } - if (!pBitmap1) { - RestoreState(false); - return false; - } - CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData( - nullptr, pBitmap1->GetBuffer(), - pBitmap1->GetPitch() * pBitmap1->GetHeight(), nullptr); - CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); - CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; - CGImageRef pImage = CGImageCreate( - pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), - pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, - pBitmapProvider, nullptr, true, kCGRenderingIntentDefault); - CGContextClipToMask(m_context, rect_usr, pImage); - CGContextSetRGBFillColor(m_context, FXARGB_R(argb) / 255.f, - FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, - FXARGB_A(argb) / 255.f); - CGContextFillRect(m_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 (!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++) { - uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row); - for (int col = 0; col < pBitmap1->GetWidth(); col++) { - pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f); - pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f); - pScanline[2] = (uint8_t)(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(m_context, (CGBlendMode)blend_mode); - CGContextDrawImage(m_context, rect_usr, image); - CGImageRelease(image); - CGContextRelease(ctx); - if (pBitmap1 != pBitmap) { - delete pBitmap1; - } - RestoreState(false); - return true; -} - -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, - uint32_t flags, - int blend_type) { - SaveState(); - if (clipRect) { - CGContextBeginPath(m_context); - CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, - clipRect->Width(), clipRect->Height()); - rect_clip = CGRectApplyAffineTransform(rect_clip, m_foxitDevice2User); - CGContextAddRect(m_context, rect_clip); - CGContextClip(m_context); - } - CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height); - rect = CGRectApplyAffineTransform(rect, m_foxitDevice2User); - if (FXDIB_BICUBIC_INTERPOL == flags) - CGContextSetInterpolationQuality(m_context, kCGInterpolationHigh); - else if (FXDIB_DOWNSAMPLE == flags) - CGContextSetInterpolationQuality(m_context, kCGInterpolationNone); - else - CGContextSetInterpolationQuality(m_context, kCGInterpolationMedium); - - CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height, nullptr); - CFX_DIBitmap* pBitmap1 = nullptr; - if (pBitmap->IsAlphaMask()) { - if (pBitmap->GetBuffer()) - pBitmap1 = (CFX_DIBitmap*)pBitmap; - else - pBitmap1 = pBitmap->Clone(); - if (!pBitmap1) { - RestoreState(false); - return false; - } - CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData( - nullptr, pBitmap1->GetBuffer(), - pBitmap1->GetPitch() * pBitmap1->GetHeight(), nullptr); - CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); - CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; - CGImageRef pImage = CGImageCreate( - pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), - pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, - pBitmapProvider, nullptr, true, kCGRenderingIntentDefault); - CGContextClipToMask(m_context, rect, pImage); - CGContextSetRGBFillColor(m_context, FXARGB_R(argb) / 255.f, - FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, - FXARGB_A(argb) / 255.f); - CGContextFillRect(m_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 (!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++) { - uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row); - for (int col = 0; col < pBitmap1->GetWidth(); col++) { - pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f); - pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f); - pScanline[2] = (uint8_t)(pScanline[2] * pScanline[3] / 255.f + .5f); - pScanline += 4; - } - } - } - CGContextRef ctx = createContextWithBitmap(pBitmap1); - CGImageRef image = CGBitmapContextCreateImage(ctx); - CGContextDrawImage(m_context, rect, image); - CGImageRelease(image); - CGContextRelease(ctx); - if (pBitmap1 != pBitmap) - delete pBitmap1; - - RestoreState(false); - return true; -} - -bool CFX_QuartzDeviceDriver::StartDIBits(const CFX_DIBSource* pBitmap, - int bitmap_alpha, - uint32_t color, - const CFX_Matrix* pMatrix, - uint32_t flags, - void*& handle, - int blend_type) { - return false; -} - -bool CFX_QuartzDeviceDriver::CG_DrawGlyphRun(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - const CFX_Matrix* pGlyphMatrix, - const CFX_Matrix* pObject2Device, - FX_FLOAT font_size, - uint32_t argb) { - if (nChars == 0) - return true; - - CQuartz2D& quartz2d = - static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData()) - ->m_quartz2d; - if (!pFont->GetPlatformFont()) { - if (pFont->GetPsName() == "DFHeiStd-W5") - return false; - - pFont->SetPlatformFont( - quartz2d.CreateFont(pFont->GetFontData(), pFont->GetSize())); - if (!pFont->GetPlatformFont()) { - return false; - } - } - CFX_FixedBufGrow<uint16_t, 32> glyph_indices(nChars); - CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars); - for (int i = 0; i < nChars; i++) { - glyph_indices[i] = pCharPos[i].m_ExtGID; - glyph_positions[i].x = pCharPos[i].m_OriginX; - glyph_positions[i].y = pCharPos[i].m_OriginY; - } - CFX_Matrix text_matrix; - if (pObject2Device) - text_matrix.Concat(*pObject2Device); - - CGAffineTransform matrix_cg = - CGAffineTransformMake(text_matrix.a, text_matrix.b, text_matrix.c, - text_matrix.d, text_matrix.e, text_matrix.f); - matrix_cg = CGAffineTransformConcat(matrix_cg, m_foxitDevice2User); - CGContextSetTextMatrix(m_context, matrix_cg); - CGContextSetFont(m_context, (CGFontRef)pFont->GetPlatformFont()); - CGContextSetFontSize(m_context, FXSYS_fabs(font_size)); - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f, - a / 255.f); - SaveState(); - if (pGlyphMatrix) { - CGPoint origin = CGPointMake(glyph_positions[0].x, glyph_positions[0].y); - origin = CGPointApplyAffineTransform(origin, matrix_cg); - CGContextTranslateCTM(m_context, origin.x, origin.y); - CGAffineTransform glyph_matrix = CGAffineTransformMake( - pGlyphMatrix->a, pGlyphMatrix->b, pGlyphMatrix->c, pGlyphMatrix->d, - pGlyphMatrix->e, pGlyphMatrix->f); - if (m_foxitDevice2User.d < 0) - glyph_matrix = CGAffineTransformInvert(glyph_matrix); - - CGContextConcatCTM(m_context, glyph_matrix); - CGContextTranslateCTM(m_context, -origin.x, -origin.y); - } - CGContextShowGlyphsAtPositions(m_context, (CGGlyph*)glyph_indices, - glyph_positions, nChars); - RestoreState(false); - return true; -} - -bool CFX_QuartzDeviceDriver::DrawDeviceText(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - const CFX_Matrix* pObject2Device, - FX_FLOAT font_size, - uint32_t color) { - if (!pFont || !m_context) - return false; - - bool bBold = pFont->IsBold(); - if (!bBold && pFont->GetSubstFont() && - pFont->GetSubstFont()->m_Weight >= 500 && - pFont->GetSubstFont()->m_Weight <= 600) { - return false; - } - SaveState(); - CGContextSetTextDrawingMode(m_context, kCGTextFillClip); - bool ret = false; - int32_t i = 0; - while (i < nChars) { - if (pCharPos[i].m_bGlyphAdjust || font_size < 0) { - if (i > 0) { - ret = CG_DrawGlyphRun(i, pCharPos, pFont, nullptr, pObject2Device, - font_size, color); - if (!ret) { - RestoreState(false); - return ret; - } - } - const FXTEXT_CHARPOS* char_pos = pCharPos + i; - CFX_Matrix glphy_matrix; - if (font_size < 0) { - glphy_matrix.Concat(-1, 0, 0, -1, 0, 0); - } - if (char_pos->m_bGlyphAdjust) { - glphy_matrix.Concat( - char_pos->m_AdjustMatrix[0], char_pos->m_AdjustMatrix[1], - char_pos->m_AdjustMatrix[2], char_pos->m_AdjustMatrix[3], 0, 0); - } - ret = CG_DrawGlyphRun(1, char_pos, pFont, &glphy_matrix, pObject2Device, - font_size, color); - if (!ret) { - RestoreState(false); - return ret; - } - i++; - pCharPos += i; - nChars -= i; - i = 0; - } else { - i++; - } - } - if (i > 0) { - ret = CG_DrawGlyphRun(i, pCharPos, pFont, nullptr, pObject2Device, - font_size, color); - } - RestoreState(false); - return ret; -} - -void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, - FX_ARGB argb, - FX_FLOAT lineWidth) { - if (!graphState) - return; - - CGContextSetLineWidth(m_context, lineWidth); - CGLineCap cap; - switch (graphState->m_LineCap) { - case CFX_GraphStateData::LineCapRound: { - cap = kCGLineCapRound; - break; - } - case CFX_GraphStateData::LineCapSquare: { - cap = kCGLineCapSquare; - break; - } - case CFX_GraphStateData::LineCapButt: - default: { cap = kCGLineCapButt; } - } - CGContextSetLineCap(m_context, cap); - CGLineJoin join; - switch (graphState->m_LineJoin) { - case CFX_GraphStateData::LineJoinRound: { - join = kCGLineJoinRound; - break; - } - case CFX_GraphStateData::LineJoinBevel: { - join = kCGLineJoinBevel; - break; - } - case CFX_GraphStateData::LineJoinMiter: - default: { join = kCGLineJoinMiter; } - } - CGContextSetLineJoin(m_context, join); - if (graphState->m_DashCount) { -#if CGFLOAT_IS_DOUBLE - CGFloat* dashArray = new CGFloat[graphState->m_DashCount]; - for (int index = 0; index < graphState->m_DashCount; ++index) { - dashArray[index] = graphState->m_DashArray[index]; - } -#else - CGFloat* dashArray = (CGFloat*)graphState->m_DashArray; -#endif - CGContextSetLineDash(m_context, graphState->m_DashPhase, dashArray, - graphState->m_DashCount); -#if CGFLOAT_IS_DOUBLE - delete[] dashArray; -#endif - } - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBStrokeColor(m_context, r / 255.f, g / 255.f, b / 255.f, - a / 255.f); -} -void CFX_QuartzDeviceDriver::setFillInfo(FX_ARGB argb) { - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f, - a / 255.f); -} -void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData) { - int32_t count = pathData->GetPointCount(); - FX_PATHPOINT* points = pathData->GetPoints(); - CGContextBeginPath(m_context); - for (int32_t i = 0; i < count; i++) { - switch (points[i].m_Flag & FXPT_TYPE) { - case FXPT_MOVETO: - CGContextMoveToPoint(m_context, points[i].m_PointX, points[i].m_PointY); - break; - case FXPT_LINETO: - CGContextAddLineToPoint(m_context, points[i].m_PointX, - points[i].m_PointY); - break; - case FXPT_BEZIERTO: { - CGContextAddCurveToPoint(m_context, points[i].m_PointX, - points[i].m_PointY, points[i + 1].m_PointX, - points[i + 1].m_PointY, points[i + 2].m_PointX, - points[i + 2].m_PointY); - i += 2; - } - } - if (points[i].m_Flag & FXPT_CLOSEFIGURE) { - CGContextClosePath(m_context); - } - } -} - -void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, - int dest_top, - int dest_width, - int dest_height, - CGRect* rect) { - int flip_y = m_foxitDevice2User.d * dest_height < 0 ? 1 : -1; - int flip_x = m_foxitDevice2User.a * dest_width > 0 ? 1 : -1; - if (flip_y >= 0 && flip_x >= 0) - return; - - if (dest_height < 0) { - dest_height = -dest_height; - dest_top -= dest_height; - } - CGRect rt = CGRectApplyAffineTransform( - CGRectMake(dest_left, dest_top, dest_width, dest_height), - m_foxitDevice2User); - CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f, - offset_y = (rt.origin.y) + rt.size.height / 2.f; - CGAffineTransform transform = CGAffineTransformIdentity; - transform = CGAffineTransformConcat( - transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y)); - transform = CGAffineTransformConcat( - transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0)); - transform = CGAffineTransformConcat( - transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y)); - CGContextConcatCTM(m_context, transform); - if (rect) - *rect = CGRectApplyAffineTransform(*rect, transform); -} - -void CFX_QuartzDeviceDriver::ClearDriver() { - if (!m_context) - return; - - for (int i = 0; i < m_saveCount; ++i) { - CGContextRestoreGState(m_context); - } - m_saveCount = 0; - if (m_context) { - CGContextRelease(m_context); - } -} -CFX_QuartzDevice::CFX_QuartzDevice() { - m_bOwnedBitmap = false; - m_pContext = nullptr; -} -CFX_QuartzDevice::~CFX_QuartzDevice() { - if (m_pContext) { - CGContextRelease(m_pContext); - } - if (m_bOwnedBitmap) { - delete GetBitmap(); - } -} -CGContextRef CFX_QuartzDevice::GetContext() { - return m_pContext; -} -bool CFX_QuartzDevice::Attach(CGContextRef context, int32_t nDeviceClass) { - if (m_pContext) { - CGContextRelease(m_pContext); - } - m_pContext = context; - CGContextRetain(m_pContext); - SetDeviceDriver( - pdfium::MakeUnique<CFX_QuartzDeviceDriver>(m_pContext, nDeviceClass)); - return true; -} - -bool CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap) { - SetBitmap(pBitmap); - m_pContext = createContextWithBitmap(pBitmap); - if (!m_pContext) - return false; - - SetDeviceDriver( - pdfium::MakeUnique<CFX_QuartzDeviceDriver>(m_pContext, FXDC_DISPLAY)); - return true; -} - -bool CFX_QuartzDevice::Create(int32_t width, - int32_t height, - FXDIB_Format format) { - if ((uint8_t)format < 32) { - return false; - } - std::unique_ptr<CFX_DIBitmap> pBitmap(new CFX_DIBitmap); - if (!pBitmap->Create(width, height, format)) - return false; - m_bOwnedBitmap = true; - return Attach(pBitmap.release()); } -#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |