diff options
Diffstat (limited to 'core/src/fxge/apple')
-rw-r--r-- | core/src/fxge/apple/apple_int.h | 437 | ||||
-rw-r--r-- | core/src/fxge/apple/fx_apple_platform.cpp | 280 | ||||
-rw-r--r-- | core/src/fxge/apple/fx_mac_imp.cpp | 155 | ||||
-rw-r--r-- | core/src/fxge/apple/fx_quartz_device.cpp | 2012 |
4 files changed, 1420 insertions, 1464 deletions
diff --git a/core/src/fxge/apple/apple_int.h b/core/src/fxge/apple/apple_int.h index 090ac0924a..ba3d0a83e8 100644 --- a/core/src/fxge/apple/apple_int.h +++ b/core/src/fxge/apple/apple_int.h @@ -7,234 +7,257 @@ #ifndef CORE_SRC_FXGE_APPLE_APPLE_INT_H_ #define CORE_SRC_FXGE_APPLE_APPLE_INT_H_ -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ #if _FX_OS_ == _FX_MACOSX_ #include <Carbon/Carbon.h> #endif typedef enum eFXIOSFONTCHARSET { - eFXFontCharsetDEFAULT = 0, - eFXFontCharsetANSI = 1, - eFXFontCharsetSYMBOL = 1 << 1, - eFXFontCharsetSHIFTJIS = 1 << 2, - eFXFontCharsetHANGEUL = 1 << 3, - eFXFontCharsetGB2312 = 1 << 4, - eFXFontCharsetCHINESEBIG5 = 1 << 5, - eFXFontCharsetTHAI = 1 << 6, - eFXFontCharsetEASTEUROPE = 1 << 7, - eFXFontCharsetRUSSIAN = 1 << 8, - eFXFontCharsetGREEK = 1 << 9, - eFXFontCharsetTURKISH = 1 << 10, - eFXFontCharsetHEBREW = 1 << 11, - eFXFontCharsetARABIC = 1 << 12, - eFXFontCharsetBALTIC = 1 << 13, + eFXFontCharsetDEFAULT = 0, + eFXFontCharsetANSI = 1, + eFXFontCharsetSYMBOL = 1 << 1, + eFXFontCharsetSHIFTJIS = 1 << 2, + eFXFontCharsetHANGEUL = 1 << 3, + eFXFontCharsetGB2312 = 1 << 4, + eFXFontCharsetCHINESEBIG5 = 1 << 5, + eFXFontCharsetTHAI = 1 << 6, + eFXFontCharsetEASTEUROPE = 1 << 7, + eFXFontCharsetRUSSIAN = 1 << 8, + eFXFontCharsetGREEK = 1 << 9, + eFXFontCharsetTURKISH = 1 << 10, + eFXFontCharsetHEBREW = 1 << 11, + eFXFontCharsetARABIC = 1 << 12, + eFXFontCharsetBALTIC = 1 << 13, } FX_IOSCHARSET; FX_IOSCHARSET FX_GetiOSCharset(int charset); typedef enum eFXIOSFONTFLAG { - eFXFontFlagBold = 1, - eFXFontFlagItalic = 1 << 1, - eFXFontFlagFixedPitch = 1 << 2, - eFXFontFlagSerif = 1 << 3, - eFXFontFlagScript = 1 << 4, + eFXFontFlagBold = 1, + eFXFontFlagItalic = 1 << 1, + eFXFontFlagFixedPitch = 1 << 2, + eFXFontFlagSerif = 1 << 3, + eFXFontFlagScript = 1 << 4, } FX_IOSFONTFLAG; typedef struct _IOS_FONTDATA { - FX_DWORD nHashCode; - const char* psName; - FX_DWORD charsets; - FX_DWORD styles; + FX_DWORD nHashCode; + const char* psName; + FX_DWORD charsets; + FX_DWORD styles; } IOS_FONTDATA; -class CQuartz2D -{ -public: - void* createGraphics(CFX_DIBitmap* bitmap); - void destroyGraphics(void* graphics); +class CQuartz2D { + public: + void* createGraphics(CFX_DIBitmap* bitmap); + void destroyGraphics(void* graphics); - void* CreateFont(const uint8_t* pFontData, FX_DWORD dwFontSize); - void DestroyFont(void* pFont); - void setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix); - FX_BOOL drawGraphicsString(void* graphics, - void* font, - FX_FLOAT fontSize, - FX_WORD* glyphIndices, - CGPoint* glyphPositions, - int32_t chars, - FX_ARGB argb, - CFX_AffineMatrix* matrix = NULL); - void saveGraphicsState(void* graphics); - void restoreGraphicsState(void* graphics); + void* CreateFont(const uint8_t* pFontData, FX_DWORD dwFontSize); + void DestroyFont(void* pFont); + void setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix); + FX_BOOL drawGraphicsString(void* graphics, + void* font, + FX_FLOAT fontSize, + FX_WORD* glyphIndices, + CGPoint* glyphPositions, + int32_t chars, + FX_ARGB argb, + CFX_AffineMatrix* matrix = NULL); + void saveGraphicsState(void* graphics); + void restoreGraphicsState(void* graphics); }; -class CApplePlatform -{ -public: - CApplePlatform() {} - ~CApplePlatform() {} +class CApplePlatform { + public: + CApplePlatform() {} + ~CApplePlatform() {} - CQuartz2D _quartz2d; + CQuartz2D _quartz2d; }; -class CFX_QuartzDeviceDriver : public IFX_RenderDeviceDriver -{ -public: - CFX_QuartzDeviceDriver(CGContextRef context, int32_t deviceClass); - virtual ~CFX_QuartzDeviceDriver(); +class CFX_QuartzDeviceDriver : public IFX_RenderDeviceDriver { + public: + CFX_QuartzDeviceDriver(CGContextRef context, int32_t deviceClass); + virtual ~CFX_QuartzDeviceDriver(); - virtual int GetDeviceCaps(int caps_id); - virtual CFX_Matrix GetCTM() const; - virtual CFX_DIBitmap* GetBackDrop() - { - return NULL; - } - virtual void* GetPlatformSurface() - { - return NULL; - } - virtual FX_BOOL IsPSPrintDriver() - { - return FALSE; - } - virtual FX_BOOL StartRendering() - { - return TRUE; - } - virtual void EndRendering() {} - virtual void SaveState(); - virtual void RestoreState(FX_BOOL bKeepSaved); - virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, + virtual int GetDeviceCaps(int caps_id); + virtual CFX_Matrix GetCTM() const; + virtual CFX_DIBitmap* GetBackDrop() { return NULL; } + virtual void* GetPlatformSurface() { return NULL; } + virtual FX_BOOL IsPSPrintDriver() { return FALSE; } + virtual FX_BOOL StartRendering() { return TRUE; } + virtual void EndRendering() {} + virtual void SaveState(); + virtual void RestoreState(FX_BOOL bKeepSaved); + virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + int fill_mode); + virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, - int fill_mode - ); - virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState - ); - virtual FX_BOOL 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 = 0, - void* pIccTransform = NULL, - int blend_type = FXDIB_BLEND_NORMAL - ); - virtual FX_BOOL SetPixel(int x, int y, FX_DWORD color, - int alpha_flag = 0, void* pIccTransform = NULL) - { - return FALSE; - } - virtual FX_BOOL FillRect(const FX_RECT* pRect, FX_DWORD fill_color, - int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL); - virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color, - int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL); - virtual FX_BOOL GetClipBox(FX_RECT* pRect); - virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE); - virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, - int dest_left, int dest_top, int blend_type, - int alpha_flag = 0, void* pIccTransform = NULL); - virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, 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 = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL); - virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD flags, void*& handle, - int alpha_flag = 0, void* pIccTransform = NULL, - int blend_type = FXDIB_BLEND_NORMAL) - { - return FALSE; - } - virtual FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause) - { - return FALSE; - } - virtual void CancelDIBits(void* handle) {} - virtual FX_BOOL DrawDeviceText(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 = 0, void* pIccTransform = NULL); - virtual void ClearDriver(); -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); - FX_BOOL CG_DrawGlypRun(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - CFX_FontCache* pCache, - const CFX_AffineMatrix* pGlyphMatrix, - const CFX_AffineMatrix* pObject2Device, - FX_FLOAT font_size, - FX_DWORD argb, - int alpha_flag, - void* pIccTransform); - void CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height, CGRect* rect = NULL); -protected: - CGContextRef _context; - CGAffineTransform _foxitDevice2User; - CGAffineTransform _user2FoxitDevice; - int32_t m_saveCount; + const CFX_GraphStateData* pGraphState); + virtual FX_BOOL 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 = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL); + virtual FX_BOOL SetPixel(int x, + int y, + FX_DWORD color, + int alpha_flag = 0, + void* pIccTransform = NULL) { + return FALSE; + } + virtual FX_BOOL FillRect(const FX_RECT* pRect, + FX_DWORD fill_color, + int alpha_flag = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL); + virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_DWORD color, + int alpha_flag = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL); + virtual FX_BOOL GetClipBox(FX_RECT* pRect); + virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, + int left, + int top, + void* pIccTransform = NULL, + FX_BOOL bDEdge = FALSE); + virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + const FX_RECT* pSrcRect, + int dest_left, + int dest_top, + int blend_type, + int alpha_flag = 0, + void* pIccTransform = NULL); + virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, + 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 = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL); + virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, + int bitmap_alpha, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD flags, + void*& handle, + int alpha_flag = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL) { + return FALSE; + } + virtual FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause) { + return FALSE; + } + virtual void CancelDIBits(void* handle) {} + virtual FX_BOOL DrawDeviceText(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 = 0, + void* pIccTransform = NULL); + virtual void ClearDriver(); - int32_t _width; - int32_t _height; - int32_t _bitsPerPixel; - int32_t _deviceClass; - int32_t _renderCaps; - int32_t _horzSize; - int32_t _vertSize; + 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); + FX_BOOL CG_DrawGlypRun(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pGlyphMatrix, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD argb, + int alpha_flag, + void* pIccTransform); + void CG_SetImageTransform(int dest_left, + int dest_top, + int dest_width, + int dest_height, + CGRect* rect = NULL); + + protected: + CGContextRef _context; + CGAffineTransform _foxitDevice2User; + CGAffineTransform _user2FoxitDevice; + int32_t m_saveCount; + + int32_t _width; + int32_t _height; + int32_t _bitsPerPixel; + int32_t _deviceClass; + int32_t _renderCaps; + int32_t _horzSize; + int32_t _vertSize; }; -class CFX_FontProvider final : public IFX_FileRead -{ -public: - virtual void Release() override - { - delete this; - } - virtual FX_FILESIZE GetSize() override - { - return (FX_FILESIZE)_totalSize; - } - virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override; +class CFX_FontProvider final : public IFX_FileRead { + public: + virtual void Release() override { delete this; } + virtual FX_FILESIZE GetSize() override { return (FX_FILESIZE)_totalSize; } + virtual FX_BOOL ReadBlock(void* buffer, + FX_FILESIZE offset, + size_t size) override; + + virtual FX_BOOL IsEOF() override { return _offSet == _totalSize; } + virtual FX_FILESIZE GetPosition() override { return (FX_FILESIZE)_offSet; } + virtual size_t ReadBlock(void* buffer, size_t size) override; + + public: + CFX_FontProvider(CGFontRef cgFont); + ~CFX_FontProvider(); + void InitTableOffset(); + unsigned long Read(unsigned long offset, + unsigned char* buffer, + unsigned long count); + + protected: + uint32_t CalcTableCheckSum(const uint32_t* table, + uint32_t numberOfBytesInTable); + uint32_t CalcTableDataRefCheckSum(CFDataRef dataRef); - virtual FX_BOOL IsEOF() override - { - return _offSet == _totalSize; - } - virtual FX_FILESIZE GetPosition() override - { - return (FX_FILESIZE)_offSet; - } - virtual size_t ReadBlock(void* buffer, size_t size) override; -public: - CFX_FontProvider(CGFontRef cgFont); - ~CFX_FontProvider(); - void InitTableOffset(); - unsigned long Read(unsigned long offset, unsigned char *buffer, unsigned long count); -protected: - uint32_t CalcTableCheckSum(const uint32_t *table, uint32_t numberOfBytesInTable); - uint32_t CalcTableDataRefCheckSum(CFDataRef dataRef); -private: - CGFontRef m_cgFont; - UInt32 m_iTableSize; - size_t _offSet; - typedef struct FontHeader { - int32_t fVersion; - uint16_t fNumTables; - uint16_t fSearchRange; - uint16_t fEntrySelector; - uint16_t fRangeShift; - } FontHeader; - typedef struct TableEntry { - uint32_t fTag; - uint32_t fCheckSum; - uint32_t fOffset; - uint32_t fLength; - } TableEntry; - FontHeader _fontHeader; - unsigned char * _tableEntries; - size_t * _tableOffsets; - int _tableCount; - int _totalSize; + private: + CGFontRef m_cgFont; + UInt32 m_iTableSize; + size_t _offSet; + typedef struct FontHeader { + int32_t fVersion; + uint16_t fNumTables; + uint16_t fSearchRange; + uint16_t fEntrySelector; + uint16_t fRangeShift; + } FontHeader; + typedef struct TableEntry { + uint32_t fTag; + uint32_t fCheckSum; + uint32_t fOffset; + uint32_t fLength; + } TableEntry; + FontHeader _fontHeader; + unsigned char* _tableEntries; + size_t* _tableOffsets; + int _tableCount; + int _totalSize; }; -uint32_t FX_GetHashCode( const FX_CHAR* pStr); -FX_DWORD FX_IOSGetMatchFamilyNameHashcode(const FX_CHAR* pFontName); +uint32_t FX_GetHashCode(const FX_CHAR* pStr); +FX_DWORD FX_IOSGetMatchFamilyNameHashcode(const FX_CHAR* pFontName); uint32_t FX_IOSGetFamilyNamesCount(); -const FX_CHAR* FX_IOSGetFamilyName( uint32_t uIndex); +const FX_CHAR* FX_IOSGetFamilyName(uint32_t uIndex); #endif #endif // CORE_SRC_FXGE_APPLE_APPLE_INT_H_ diff --git a/core/src/fxge/apple/fx_apple_platform.cpp b/core/src/fxge/apple/fx_apple_platform.cpp index 9db807c3af..95cd1a1dd8 100644 --- a/core/src/fxge/apple/fx_apple_platform.cpp +++ b/core/src/fxge/apple/fx_apple_platform.cpp @@ -7,7 +7,7 @@ #include "../../../include/fxcrt/fx_system.h" #include "../../../include/fxge/fx_ge.h" -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ #include "../../../include/fxge/fx_freetype.h" #include "../../../include/fxge/fx_ge_apple.h" @@ -16,159 +16,159 @@ #include "../ge/text_int.h" #include "apple_int.h" -void CFX_AggDeviceDriver::InitPlatform() -{ - CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap); +void CFX_AggDeviceDriver::InitPlatform() { + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap); } -void CFX_AggDeviceDriver::DestroyPlatform() -{ - CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - if (m_pPlatformGraphics) { - quartz2d.destroyGraphics(m_pPlatformGraphics); - m_pPlatformGraphics = NULL; - } +void CFX_AggDeviceDriver::DestroyPlatform() { + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + if (m_pPlatformGraphics) { + quartz2d.destroyGraphics(m_pPlatformGraphics); + m_pPlatformGraphics = NULL; + } } void CFX_FaceCache::InitPlatform() {} void CFX_FaceCache::DestroyPlatform() {} -CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font * pFont, - FX_DWORD glyph_index, - const CFX_AffineMatrix * pMatrix, - int dest_width, - int anti_alias) -{ - return NULL; +CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext( + CFX_Font* pFont, + FX_DWORD glyph_index, + const CFX_AffineMatrix* pMatrix, + int dest_width, + int anti_alias) { + return NULL; } -static FX_BOOL _CGDrawGlyphRun(CGContextRef pContext, - int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - CFX_FontCache* pCache, - const CFX_AffineMatrix* pObject2Device, - FX_FLOAT font_size, - FX_DWORD argb, - int alpha_flag, - void* pIccTransform) -{ - if (nChars == 0) { - return TRUE; - } - CFX_AffineMatrix new_matrix; - FX_BOOL bNegSize = font_size < 0; - if (bNegSize) { - font_size = -font_size; - } - FX_FLOAT ori_x = pCharPos[0].m_OriginX, ori_y = pCharPos[0].m_OriginY; - new_matrix.Transform(ori_x, ori_y); - if (pObject2Device) { - new_matrix.Concat(*pObject2Device); +static FX_BOOL _CGDrawGlyphRun(CGContextRef pContext, + int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD argb, + int alpha_flag, + void* pIccTransform) { + if (nChars == 0) { + return TRUE; + } + CFX_AffineMatrix new_matrix; + FX_BOOL bNegSize = font_size < 0; + if (bNegSize) { + font_size = -font_size; + } + FX_FLOAT ori_x = pCharPos[0].m_OriginX, ori_y = pCharPos[0].m_OriginY; + new_matrix.Transform(ori_x, ori_y); + if (pObject2Device) { + new_matrix.Concat(*pObject2Device); + } + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + if (!pFont->m_pPlatformFont) { + if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { + return FALSE; } - CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - if (!pFont->m_pPlatformFont) { - if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { - return FALSE; - } - pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize); - if (NULL == pFont->m_pPlatformFont) { - return FALSE; - } - } - CFX_FixedBufGrow<FX_WORD, 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; - if (bNegSize) { - glyph_positions[i].x = -pCharPos[i].m_OriginX; - } else { - glyph_positions[i].x = pCharPos[i].m_OriginX; - } - glyph_positions[i].y = pCharPos[i].m_OriginY; + pFont->m_pPlatformFont = + quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize); + if (NULL == pFont->m_pPlatformFont) { + return FALSE; } + } + CFX_FixedBufGrow<FX_WORD, 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; if (bNegSize) { - new_matrix.a = -new_matrix.a; + glyph_positions[i].x = -pCharPos[i].m_OriginX; } else { - new_matrix.b = -new_matrix.b; - new_matrix.d = -new_matrix.d; + glyph_positions[i].x = pCharPos[i].m_OriginX; } - quartz2d.setGraphicsTextMatrix(pContext, &new_matrix); - return quartz2d.drawGraphicsString(pContext, - pFont->m_pPlatformFont, - font_size, - glyph_indices, - glyph_positions, - nChars, - argb, - NULL); + glyph_positions[i].y = pCharPos[i].m_OriginY; + } + if (bNegSize) { + new_matrix.a = -new_matrix.a; + } else { + new_matrix.b = -new_matrix.b; + new_matrix.d = -new_matrix.d; + } + quartz2d.setGraphicsTextMatrix(pContext, &new_matrix); + return quartz2d.drawGraphicsString(pContext, pFont->m_pPlatformFont, + font_size, glyph_indices, glyph_positions, + nChars, argb, NULL); } -static void _DoNothing(void *info, const void *data, size_t size) {} -FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, - const FXTEXT_CHARPOS * pCharPos, - CFX_Font * pFont, - CFX_FontCache * pCache, - const CFX_AffineMatrix * pObject2Device, - FX_FLOAT font_size, - FX_DWORD argb, - int alpha_flag, void* pIccTransform) -{ - if (!pFont) { - return FALSE; - } - FX_BOOL bBold = pFont->IsBold(); - if (!bBold && pFont->GetSubstFont() && - pFont->GetSubstFont()->m_Weight >= 500 && - pFont->GetSubstFont()->m_Weight <= 600) { - return FALSE; - } - for (int i = 0; i < nChars; i ++) { - if (pCharPos[i].m_bGlyphAdjust) { - return FALSE; - } +static void _DoNothing(void* info, const void* data, size_t size) {} +FX_BOOL CFX_AggDeviceDriver::DrawDeviceText( + int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD argb, + int alpha_flag, + void* pIccTransform) { + if (!pFont) { + return FALSE; + } + FX_BOOL bBold = pFont->IsBold(); + if (!bBold && pFont->GetSubstFont() && + pFont->GetSubstFont()->m_Weight >= 500 && + pFont->GetSubstFont()->m_Weight <= 600) { + return FALSE; + } + for (int i = 0; i < nChars; i++) { + if (pCharPos[i].m_bGlyphAdjust) { + return FALSE; } - CGContextRef ctx = CGContextRef(m_pPlatformGraphics); - if (NULL == ctx) { - return FALSE; + } + CGContextRef ctx = CGContextRef(m_pPlatformGraphics); + if (NULL == ctx) { + return FALSE; + } + CGContextSaveGState(ctx); + CGContextSetTextDrawingMode(ctx, kCGTextFillClip); + CGRect rect_cg; + CGImageRef pImageCG = NULL; + if (m_pClipRgn) { + rect_cg = + CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, + m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height()); + const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask(); + if (pClipMask) { + CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData( + NULL, pClipMask->GetBuffer(), + pClipMask->GetPitch() * pClipMask->GetHeight(), _DoNothing); + CGFloat decode_f[2] = {255.f, 0.f}; + pImageCG = CGImageMaskCreate( + pClipMask->GetWidth(), pClipMask->GetHeight(), 8, 8, + pClipMask->GetPitch(), pClipMaskDataProvider, decode_f, FALSE); + CGDataProviderRelease(pClipMaskDataProvider); } - CGContextSaveGState(ctx); - CGContextSetTextDrawingMode(ctx, kCGTextFillClip); - CGRect rect_cg; - CGImageRef pImageCG = NULL; - if (m_pClipRgn) { - rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height()); - const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask(); - if (pClipMask) { - CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL, - pClipMask->GetBuffer(), - pClipMask->GetPitch() * pClipMask->GetHeight(), - _DoNothing); - CGFloat decode_f[2] = {255.f, 0.f}; - pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(), - 8, 8, pClipMask->GetPitch(), pClipMaskDataProvider, - decode_f, FALSE); - CGDataProviderRelease(pClipMaskDataProvider); - } - } else { - rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight()); - } - rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg); - if (pImageCG) { - CGContextClipToMask(ctx, rect_cg, pImageCG); - } else { - CGContextClipToRect(ctx, rect_cg); - } - FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform); - if (pImageCG) { - CGImageRelease(pImageCG); - } - CGContextRestoreGState(ctx); - return ret; + } else { + rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight()); + } + rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg); + if (pImageCG) { + CGContextClipToMask(ctx, rect_cg, pImageCG); + } else { + CGContextClipToRect(ctx, rect_cg); + } + FX_BOOL ret = + _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, + font_size, argb, alpha_flag, pIccTransform); + if (pImageCG) { + CGImageRelease(pImageCG); + } + CGContextRestoreGState(ctx); + return ret; } -void CFX_Font::ReleasePlatformResource() -{ - if (m_pPlatformFont) { - CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - quartz2d.DestroyFont(m_pPlatformFont); - m_pPlatformFont = NULL; - } +void CFX_Font::ReleasePlatformResource() { + if (m_pPlatformFont) { + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + quartz2d.DestroyFont(m_pPlatformFont); + m_pPlatformFont = NULL; + } } #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ diff --git a/core/src/fxge/apple/fx_mac_imp.cpp b/core/src/fxge/apple/fx_mac_imp.cpp index b32a9a8617..9af8804d48 100644 --- a/core/src/fxge/apple/fx_mac_imp.cpp +++ b/core/src/fxge/apple/fx_mac_imp.cpp @@ -8,10 +8,9 @@ #include "apple_int.h" #if _FX_OS_ == _FX_MACOSX_ static const struct { - const FX_CHAR* m_pName; - const FX_CHAR* m_pSubstName; -} -Base14Substs[] = { + const FX_CHAR* m_pName; + const FX_CHAR* m_pSubstName; +} Base14Substs[] = { {"Courier", "Courier New"}, {"Courier-Bold", "Courier New Bold"}, {"Courier-BoldOblique", "Courier New Bold Italic"}, @@ -25,85 +24,91 @@ Base14Substs[] = { {"Times-BoldItalic", "Times New Roman Bold Italic"}, {"Times-Italic", "Times New Roman Italic"}, }; -class CFX_MacFontInfo : public CFX_FolderFontInfo -{ -public: - virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* family, int& iExact); +class CFX_MacFontInfo : public CFX_FolderFontInfo { + public: + virtual void* MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* family, + int& iExact); }; #define JAPAN_GOTHIC "Hiragino Kaku Gothic Pro W6" #define JAPAN_MINCHO "Hiragino Mincho Pro W6" -static void GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family) -{ - if (face.Find("Gothic") >= 0) { - face = JAPAN_GOTHIC; - return; - } - if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { - face = JAPAN_GOTHIC; - } else { - face = JAPAN_MINCHO; - } +static void GetJapanesePreference(CFX_ByteString& face, + int weight, + int picth_family) { + if (face.Find("Gothic") >= 0) { + face = JAPAN_GOTHIC; + return; + } + if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { + face = JAPAN_GOTHIC; + } else { + face = JAPAN_MINCHO; + } } -void* CFX_MacFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* cstr_face, int& iExact) -{ - CFX_ByteString face = cstr_face; - int iBaseFont; - for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++) - if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { - face = Base14Substs[iBaseFont].m_pSubstName; - iExact = TRUE; - break; - } - if (iBaseFont < 12) { - return GetFont(face); - } - void* p; - if (m_FontList.Lookup(face, p)) { - return p; - } - if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { - return GetFont("Courier New"); - } - if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_SYMBOL_CHARSET) { - return NULL; - } - switch (charset) { - case FXFONT_SHIFTJIS_CHARSET: - GetJapanesePreference(face, weight, pitch_family); - break; - case FXFONT_GB2312_CHARSET: - face = "STSong"; - break; - case FXFONT_HANGEUL_CHARSET: - face = "AppleMyungjo"; - break; - case FXFONT_CHINESEBIG5_CHARSET: - face = "LiSong Pro Light"; - } - if (m_FontList.Lookup(face, p)) { - return p; +void* CFX_MacFontInfo::MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* cstr_face, + int& iExact) { + CFX_ByteString face = cstr_face; + int iBaseFont; + for (iBaseFont = 0; iBaseFont < 12; iBaseFont++) + if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { + face = Base14Substs[iBaseFont].m_pSubstName; + iExact = TRUE; + break; } + if (iBaseFont < 12) { + return GetFont(face); + } + void* p; + if (m_FontList.Lookup(face, p)) { + return p; + } + if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { + return GetFont("Courier New"); + } + if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_SYMBOL_CHARSET) { return NULL; + } + switch (charset) { + case FXFONT_SHIFTJIS_CHARSET: + GetJapanesePreference(face, weight, pitch_family); + break; + case FXFONT_GB2312_CHARSET: + face = "STSong"; + break; + case FXFONT_HANGEUL_CHARSET: + face = "AppleMyungjo"; + break; + case FXFONT_CHINESEBIG5_CHARSET: + face = "LiSong Pro Light"; + } + if (m_FontList.Lookup(face, p)) { + return p; + } + return NULL; } -IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() -{ - CFX_MacFontInfo* pInfo = FX_NEW CFX_MacFontInfo; - if (!pInfo) { - return NULL; - } - pInfo->AddPath("~/Library/Fonts"); - pInfo->AddPath("/Library/Fonts"); - pInfo->AddPath("/System/Library/Fonts"); - return pInfo; +IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() { + CFX_MacFontInfo* pInfo = FX_NEW CFX_MacFontInfo; + if (!pInfo) { + return NULL; + } + pInfo->AddPath("~/Library/Fonts"); + pInfo->AddPath("/Library/Fonts"); + pInfo->AddPath("/System/Library/Fonts"); + return pInfo; } -void CFX_GEModule::InitPlatform() -{ - m_pPlatformData = FX_NEW CApplePlatform; - m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); +void CFX_GEModule::InitPlatform() { + m_pPlatformData = FX_NEW CApplePlatform; + m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); } -void CFX_GEModule::DestroyPlatform() -{ - delete (CApplePlatform *)m_pPlatformData; - m_pPlatformData = NULL; +void CFX_GEModule::DestroyPlatform() { + delete (CApplePlatform*)m_pPlatformData; + m_pPlatformData = NULL; } #endif diff --git a/core/src/fxge/apple/fx_quartz_device.cpp b/core/src/fxge/apple/fx_quartz_device.cpp index c1004d69db..80b9517629 100644 --- a/core/src/fxge/apple/fx_quartz_device.cpp +++ b/core/src/fxge/apple/fx_quartz_device.cpp @@ -11,1127 +11,1055 @@ #include "../dib/dib_int.h" #include "../ge/text_int.h" -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ #include "apple_int.h" #include "../../../include/fxge/fx_ge_apple.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) { - return NULL; - } - CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little; - switch (pBitmap->GetFormat()) { - case FXDIB_Rgb32: - bmpInfo |= kCGImageAlphaNoneSkipFirst; - break; - case FXDIB_Argb: - default: - return NULL; - } - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(), - pBitmap->GetWidth(), - pBitmap->GetHeight(), - 8, - pBitmap->GetPitch(), - colorSpace, - bmpInfo); - CGColorSpaceRelease(colorSpace); - return context; +void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap) { + if (!pBitmap) { + return NULL; + } + CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little; + switch (pBitmap->GetFormat()) { + case FXDIB_Rgb32: + bmpInfo |= kCGImageAlphaNoneSkipFirst; + break; + case FXDIB_Argb: + default: + return NULL; + } + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate( + pBitmap->GetBuffer(), pBitmap->GetWidth(), pBitmap->GetHeight(), 8, + pBitmap->GetPitch(), colorSpace, bmpInfo); + CGColorSpaceRelease(colorSpace); + return context; } -void CQuartz2D::destroyGraphics(void* graphics) -{ - if (graphics) { - CGContextRelease((CGContextRef) graphics); - } +void CQuartz2D::destroyGraphics(void* graphics) { + if (graphics) { + CGContextRelease((CGContextRef)graphics); + } } -void* CQuartz2D::CreateFont(const uint8_t* pFontData, FX_DWORD dwFontSize) -{ - CGDataProviderRef pDataProvider = CGDataProviderCreateWithData(NULL, pFontData, (size_t)dwFontSize, NULL); - if (NULL == pDataProvider) { - return NULL; - } - CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider); - CGDataProviderRelease(pDataProvider); - return pCGFont; +void* CQuartz2D::CreateFont(const uint8_t* pFontData, FX_DWORD dwFontSize) { + CGDataProviderRef pDataProvider = + CGDataProviderCreateWithData(NULL, pFontData, (size_t)dwFontSize, NULL); + if (NULL == pDataProvider) { + return NULL; + } + CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider); + CGDataProviderRelease(pDataProvider); + return pCGFont; } -void CQuartz2D::DestroyFont(void* pFont) -{ - CGFontRelease((CGFontRef)pFont); +void CQuartz2D::DestroyFont(void* pFont) { + CGFontRelease((CGFontRef)pFont); } -void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* 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)); +void CQuartz2D::setGraphicsTextMatrix(void* graphics, + CFX_AffineMatrix* 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)); } -FX_BOOL CQuartz2D::drawGraphicsString(void* graphics, - void* font, - FX_FLOAT fontSize, - FX_WORD* glyphIndices, - CGPoint* glyphPositions, - int32_t charsCount, - FX_ARGB argb, - CFX_AffineMatrix* matrix ) -{ - if (!graphics) { - return FALSE; - } - CGContextRef context = (CGContextRef) graphics; - CGContextSetFont(context, (CGFontRef)font); - CGContextSetFontSize(context, fontSize); - if (matrix) { - CGAffineTransform m = CGContextGetTextMatrix(context); - m = CGAffineTransformConcat(m, - CGAffineTransformMake(matrix->a, - matrix->b, - matrix->c, - matrix->d, - matrix->e, - matrix->f)); - CGContextSetTextMatrix(context, m); - } - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBFillColor(context, - r / 255.f, - g / 255.f, - b / 255.f, - a / 255.f); - CGContextSaveGState(context); +FX_BOOL CQuartz2D::drawGraphicsString(void* graphics, + void* font, + FX_FLOAT fontSize, + FX_WORD* glyphIndices, + CGPoint* glyphPositions, + int32_t charsCount, + FX_ARGB argb, + CFX_AffineMatrix* matrix) { + if (!graphics) { + return FALSE; + } + CGContextRef context = (CGContextRef)graphics; + CGContextSetFont(context, (CGFontRef)font); + CGContextSetFontSize(context, fontSize); + if (matrix) { + CGAffineTransform m = CGContextGetTextMatrix(context); + m = CGAffineTransformConcat( + m, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d, + matrix->e, matrix->f)); + CGContextSetTextMatrix(context, m); + } + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBFillColor(context, r / 255.f, g / 255.f, b / 255.f, a / 255.f); + CGContextSaveGState(context); #if CGFLOAT_IS_DOUBLE - CGPoint* glyphPositionsCG = new CGPoint[charsCount]; - if (!glyphPositionsCG) { - return FALSE; - } - for (int index = 0; index < charsCount; ++index) { - glyphPositionsCG[index].x = glyphPositions[index].x; - glyphPositionsCG[index].y = glyphPositions[index].y; - } + CGPoint* glyphPositionsCG = new CGPoint[charsCount]; + if (!glyphPositionsCG) { + return FALSE; + } + for (int index = 0; index < charsCount; ++index) { + glyphPositionsCG[index].x = glyphPositions[index].x; + glyphPositionsCG[index].y = glyphPositions[index].y; + } #else - CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions; + CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions; #endif - CGContextShowGlyphsAtPositions(context, - (CGGlyph *) glyphIndices, - glyphPositionsCG, - charsCount); + CGContextShowGlyphsAtPositions(context, (CGGlyph*)glyphIndices, + glyphPositionsCG, charsCount); #if CGFLOAT_IS_DOUBLE - delete[] glyphPositionsCG; + delete[] glyphPositionsCG; #endif - CGContextRestoreGState(context); - return TRUE; + CGContextRestoreGState(context); + return TRUE; } -void CQuartz2D::saveGraphicsState(void * graphics) -{ - if (graphics) { - CGContextSaveGState((CGContextRef) graphics); - } +void CQuartz2D::saveGraphicsState(void* graphics) { + if (graphics) { + CGContextSaveGState((CGContextRef)graphics); + } } -void CQuartz2D::restoreGraphicsState(void * graphics) -{ - if (graphics) { - CGContextRestoreGState((CGContextRef) graphics); - } +void CQuartz2D::restoreGraphicsState(void* graphics) { + if (graphics) { + CGContextRestoreGState((CGContextRef)graphics); + } } -static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap) -{ - if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) { - return NULL; - } - 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; +static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap) { + if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) { + return NULL; + } + 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; - _context = context; - _deviceClass = deviceClass; - CGContextRetain(_context); - CGRect r = CGContextGetClipBoundingBox(context); - _width = FXSYS_round(r.size.width); - _height = FXSYS_round(r.size.height); - _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | - FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | - FXRC_BIT_MASK | FXRC_ALPHA_MASK; - if (_deviceClass != FXDC_DISPLAY) { - } else { - CGImageRef image = CGBitmapContextCreateImage(_context); - if (image) { - _renderCaps |= FXRC_GET_BITS; - _width = CGImageGetWidth(image); - _height = CGImageGetHeight(image); - CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image); - if (kCGImageAlphaPremultipliedFirst == alphaInfo || - kCGImageAlphaPremultipliedLast == alphaInfo || - kCGImageAlphaOnly == alphaInfo) { - _renderCaps |= FXRC_ALPHA_OUTPUT; - } - } - CGImageRelease(image); - } - CGAffineTransform ctm = CGContextGetCTM(_context); - CGContextSaveGState(_context); - m_saveCount++; - if (ctm.d >= 0) { - CGFloat offset_x, offset_y; - offset_x = ctm.tx; - offset_y = ctm.ty; - CGContextTranslateCTM(_context, -offset_x, -offset_y); - CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, _height + offset_y)); +CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context, + int32_t deviceClass) { + m_saveCount = 0; + _context = context; + _deviceClass = deviceClass; + CGContextRetain(_context); + CGRect r = CGContextGetClipBoundingBox(context); + _width = FXSYS_round(r.size.width); + _height = FXSYS_round(r.size.height); + _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | FXRC_ALPHA_PATH | + FXRC_ALPHA_IMAGE | FXRC_BIT_MASK | FXRC_ALPHA_MASK; + if (_deviceClass != FXDC_DISPLAY) { + } else { + CGImageRef image = CGBitmapContextCreateImage(_context); + if (image) { + _renderCaps |= FXRC_GET_BITS; + _width = CGImageGetWidth(image); + _height = CGImageGetHeight(image); + CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image); + if (kCGImageAlphaPremultipliedFirst == alphaInfo || + kCGImageAlphaPremultipliedLast == alphaInfo || + kCGImageAlphaOnly == alphaInfo) { + _renderCaps |= FXRC_ALPHA_OUTPUT; + } } - _foxitDevice2User = CGAffineTransformIdentity; - _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User); + CGImageRelease(image); + } + CGAffineTransform ctm = CGContextGetCTM(_context); + CGContextSaveGState(_context); + m_saveCount++; + if (ctm.d >= 0) { + CGFloat offset_x, offset_y; + offset_x = ctm.tx; + offset_y = ctm.ty; + CGContextTranslateCTM(_context, -offset_x, -offset_y); + CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, + _height + offset_y)); + } + _foxitDevice2User = CGAffineTransformIdentity; + _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User); } -CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver() -{ +CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver() { + CGContextRestoreGState(_context); + m_saveCount--; + for (int i = 0; i < m_saveCount; ++i) { CGContextRestoreGState(_context); - m_saveCount--; - for (int i = 0; i < m_saveCount; ++i) { - CGContextRestoreGState(_context); + } + if (_context) { + CGContextRelease(_context); + } +} +int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID) { + switch (capsID) { + case FXDC_DEVICE_CLASS: { + return _deviceClass; } - if (_context) { - CGContextRelease(_context); + case FXDC_PIXEL_WIDTH: { + return _width; } -} -int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID) -{ - switch (capsID) { - case FXDC_DEVICE_CLASS: { - return _deviceClass; - } - case FXDC_PIXEL_WIDTH: { - return _width; - } - case FXDC_PIXEL_HEIGHT: { - return _height; - } - case FXDC_BITS_PIXEL: { - return 32; - } - case FXDC_RENDER_CAPS: { - return _renderCaps; - } - default: { - return 0; - } + case FXDC_PIXEL_HEIGHT: { + return _height; + } + case FXDC_BITS_PIXEL: { + return 32; + } + case FXDC_RENDER_CAPS: { + return _renderCaps; } + default: { return 0; } + } } -CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const -{ - CGAffineTransform ctm = CGContextGetCTM(_context); - return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty); +CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const { + CGAffineTransform ctm = CGContextGetCTM(_context); + return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty); } -void CFX_QuartzDeviceDriver::SaveState() -{ +void CFX_QuartzDeviceDriver::SaveState() { + CGContextSaveGState(_context); + m_saveCount++; +} +void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved) { + CGContextRestoreGState(_context); + if (isKeepSaved) { CGContextSaveGState(_context); - m_saveCount++; + } else { + m_saveCount--; + } } -void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved ) -{ - CGContextRestoreGState(_context); - if (isKeepSaved) { - CGContextSaveGState(_context); - } else { - m_saveCount--; - } +FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData, + const CFX_AffineMatrix* 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, _foxitDevice2User); + CGContextConcatCTM(_context, m); + setPathToContext(pathData); + RestoreState(FALSE); + if ((fillMode & 3) == FXFILL_WINDING) { + CGContextClip(_context); + } else { + CGContextEOClip(_context); + } + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData, - const CFX_AffineMatrix* 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, _foxitDevice2User); - CGContextConcatCTM(_context, m); - setPathToContext(pathData); - RestoreState(FALSE); - if ((fillMode & 3) == FXFILL_WINDING) { - CGContextClip(_context); - } else { - CGContextEOClip(_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; } -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; +FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke( + const CFX_PathData* pathData, + const CFX_AffineMatrix* 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, _foxitDevice2User); + CGContextConcatCTM(_context, m); + FX_FLOAT lineWidth = getLineWidth(graphState, m); + setStrokeInfo(graphState, 0xFF000000, lineWidth); + setPathToContext(pathData); + CGContextReplacePathWithStrokedPath(_context); + RestoreState(FALSE); + CGContextClip(_context); + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke(const CFX_PathData* pathData, - const CFX_AffineMatrix* 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, _foxitDevice2User); - CGContextConcatCTM(_context, m); - FX_FLOAT lineWidth = getLineWidth(graphState, m); - setStrokeInfo(graphState, 0xFF000000, lineWidth); - setPathToContext(pathData); - CGContextReplacePathWithStrokedPath(_context); - RestoreState(FALSE); - CGContextClip(_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; } -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; +FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData, + const CFX_AffineMatrix* matrix, + const CFX_GraphStateData* graphState, + FX_DWORD fillArgb, + FX_DWORD strokeArgb, + int fillMode, + int alpha_flag, + void* pIccTransform, + int blend_type) { + SaveState(); + CGBlendMode mode = GetCGBlendMode(blend_type); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, mode); + } + CGAffineTransform m = CGAffineTransformIdentity; + if (matrix) { + m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), + matrix->GetD(), matrix->GetE(), matrix->GetF()); + } + m = CGAffineTransformConcat(m, _foxitDevice2User); + CGContextConcatCTM(_context, m); + int pathMode = 0; + if (graphState && strokeArgb) { + CGContextSetMiterLimit(_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(_context, false); + } + if (pathMode == 4) { + CGContextStrokePath(_context); + } else if (pathMode == 1) { + CGContextFillPath(_context); + } else if (pathMode == 2) { + CGContextEOFillPath(_context); + } else if (pathMode == 5) { + CGContextDrawPath(_context, kCGPathFillStroke); + } else if (pathMode == 6) { + CGContextDrawPath(_context, kCGPathEOFillStroke); + } + RestoreState(FALSE); + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData, - const CFX_AffineMatrix* matrix, - const CFX_GraphStateData* graphState, - FX_DWORD fillArgb, - FX_DWORD strokeArgb, - int fillMode, - int alpha_flag, - void* pIccTransform, - int blend_type - ) -{ - SaveState(); - CGBlendMode mode = GetCGBlendMode(blend_type); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, mode); - } - CGAffineTransform m = CGAffineTransformIdentity; - if (matrix) { - m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF()); - } - m = CGAffineTransformConcat(m, _foxitDevice2User); - CGContextConcatCTM(_context, m); - int pathMode = 0; - if (graphState && strokeArgb) { - CGContextSetMiterLimit(_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(_context, false); - } - if (pathMode == 4) { - CGContextStrokePath(_context); - } else if (pathMode == 1) { - CGContextFillPath(_context); - } else if (pathMode == 2) { - CGContextEOFillPath(_context); - } else if (pathMode == 5) { - CGContextDrawPath(_context, kCGPathFillStroke); - } else if (pathMode == 6) { - CGContextDrawPath(_context, kCGPathEOFillStroke); - } - RestoreState(FALSE); - return TRUE; +FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect, + FX_ARGB fillArgb, + int alphaFlag, + void* iccTransform, + int blend_type) { + CGBlendMode mode = GetCGBlendMode(blend_type); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, mode); + } + CGRect rect_fx = + CGRectMake(rect->left, rect->top, rect->Width(), rect->Height()); + CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User); + int32_t a, r, g, b; + ArgbDecode(fillArgb, a, r, g, b); + CGContextSetRGBFillColor(_context, r / 255.f, g / 255.f, b / 255.f, + a / 255.f); + CGContextFillRect(_context, rect_usr); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, kCGBlendModeNormal); + } + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect, - FX_ARGB fillArgb, - int alphaFlag , - void* iccTransform , - int blend_type ) -{ - CGBlendMode mode = GetCGBlendMode(blend_type); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, mode); - } - CGRect rect_fx = CGRectMake(rect->left, rect->top, rect->Width(), rect->Height()); - CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User); - int32_t a, r, g, b; - ArgbDecode(fillArgb, a, r, g, b); - CGContextSetRGBFillColor(_context, - r / 255.f, - g / 255.f, - b / 255.f, +FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_DWORD argb, + int alphaFlag, + void* iccTransform, + int blend_type) { + CGBlendMode mode = GetCGBlendMode(blend_type); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, mode); + } + CGPoint pt = + CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2User); + x1 = pt.x; + y1 = pt.y; + pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User); + x2 = pt.x; + y2 = pt.y; + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBStrokeColor(_context, r / 255.f, g / 255.f, b / 255.f, a / 255.f); - CGContextFillRect(_context, rect_usr); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, kCGBlendModeNormal); - } - return TRUE; + CGContextMoveToPoint(_context, x1, y1); + CGContextAddLineToPoint(_context, x2, y2); + CGContextStrokePath(_context); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, kCGBlendModeNormal); + } + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, - FX_FLOAT y1, - FX_FLOAT x2, - FX_FLOAT y2, - FX_DWORD argb, - int alphaFlag , - void* iccTransform , - int blend_type ) -{ - CGBlendMode mode = GetCGBlendMode(blend_type); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, mode); - } - CGPoint pt = CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2User); - x1 = pt.x; - y1 = pt.y; - pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User); - x2 = pt.x; - y2 = pt.y; - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBStrokeColor(_context, - r / 255.f, - g / 255.f, - b / 255.f, - a / 255.f); - CGContextMoveToPoint(_context, x1, y1); - CGContextAddLineToPoint(_context, x2, y2); - CGContextStrokePath(_context); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, kCGBlendModeNormal); - } - return TRUE; +FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) { + CGRect r = CGContextGetClipBoundingBox(_context); + r = CGRectApplyAffineTransform(r, _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; } -FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) -{ - CGRect r = CGContextGetClipBoundingBox(_context); - r = CGRectApplyAffineTransform(r, _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; -} -FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap, - int32_t left, - int32_t top, - void* pIccTransform, - FX_BOOL bDEdge) -{ - if (FXDC_PRINTER == _deviceClass) { - return FALSE; - } - if (bitmap->GetBPP() < 32) { - return FALSE; - } - if (!(_renderCaps | FXRC_GET_BITS)) { - return FALSE; - } - CGPoint pt = CGPointMake(left, top); - pt = CGPointApplyAffineTransform(pt, _foxitDevice2User); - CGAffineTransform ctm = CGContextGetCTM(_context); - pt.x *= FXSYS_fabs(ctm.a); - pt.y *= FXSYS_fabs(ctm.d); - CGImageRef image = CGBitmapContextCreateImage(_context); - if (NULL == image) { - return FALSE; - } - CGFloat width = (CGFloat) bitmap->GetWidth(); - CGFloat height = (CGFloat) bitmap->GetHeight(); - if (width + pt.x > _width) { - width -= (width + pt.x - _width); - } - if (height + pt.y > _height) { - height -= (height + pt.y - _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()) { - 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; - } +FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap, + int32_t left, + int32_t top, + void* pIccTransform, + FX_BOOL bDEdge) { + if (FXDC_PRINTER == _deviceClass) { + return FALSE; + } + if (bitmap->GetBPP() < 32) { + return FALSE; + } + if (!(_renderCaps | FXRC_GET_BITS)) { + return FALSE; + } + CGPoint pt = CGPointMake(left, top); + pt = CGPointApplyAffineTransform(pt, _foxitDevice2User); + CGAffineTransform ctm = CGContextGetCTM(_context); + pt.x *= FXSYS_fabs(ctm.a); + pt.y *= FXSYS_fabs(ctm.d); + CGImageRef image = CGBitmapContextCreateImage(_context); + if (NULL == image) { + return FALSE; + } + CGFloat width = (CGFloat)bitmap->GetWidth(); + CGFloat height = (CGFloat)bitmap->GetHeight(); + if (width + pt.x > _width) { + width -= (width + pt.x - _width); + } + if (height + pt.y > _height) { + height -= (height + pt.y - _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()) { + 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; + } + return TRUE; } -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(); +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 { - 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(); - } + 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 ++) { - 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(_context, (CGBlendMode)blend_mode); - CGContextDrawImage(_context, rect_usr, image); - CGImageRelease(image); - CGContextRelease(ctx); + 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; + delete pBitmap1; } RestoreState(FALSE); return TRUE; -} -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); + } + if (pBitmap->GetBPP() < 32) { + pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); + } else { + if (pBitmap->GetBuffer()) { + pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { - CGContextSetInterpolationQuality(_context, kCGInterpolationMedium); + pBitmap1 = pBitmap->Clone(); } - 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; - } + } + if (NULL == pBitmap1) { + RestoreState(FALSE); + return FALSE; + } + if (pBitmap1->HasAlpha()) { + if (pBitmap1 == pBitmap) { + pBitmap1 = pBitmap->Clone(); + if (!pBitmap1) { RestoreState(FALSE); - return TRUE; - } - if (pBitmap->GetBPP() < 32) { - pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); + 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(_context, (CGBlendMode)blend_mode); + CGContextDrawImage(_context, rect_usr, image); + CGImageRelease(image); + CGContextRelease(ctx); + if (pBitmap1 != pBitmap) { + delete pBitmap1; + } + RestoreState(FALSE); + return TRUE; +} +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 { - if (pBitmap->GetBuffer()) { - pBitmap1 = (CFX_DIBitmap*)pBitmap; - } else { - pBitmap1 = pBitmap->Clone(); - } + 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 ++) { - 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(_context, rect, image); - CGImageRelease(image); - CGContextRelease(ctx); + 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; + delete pBitmap1; } RestoreState(FALSE); return TRUE; -} -FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - CFX_FontCache* pCache, - const CFX_AffineMatrix* pGlyphMatrix, - const CFX_AffineMatrix* pObject2Device, - FX_FLOAT font_size, - FX_DWORD argb, - int alpha_flag, - void* pIccTransform) -{ - if (nChars == 0) { - return TRUE; - } - CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - if (!pFont->m_pPlatformFont) { - if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { - return FALSE; - } - pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize); - if (NULL == pFont->m_pPlatformFont) { - return FALSE; - } - } - CFX_FixedBufGrow<FX_WORD, 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_AffineMatrix 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, _foxitDevice2User); - CGContextSetTextMatrix(_context, matrix_cg); - CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont); - CGContextSetFontSize(_context, FXSYS_fabs(font_size)); - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBFillColor(_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(_context, origin.x, origin.y); - CGAffineTransform glyph_matrix = CGAffineTransformMake(pGlyphMatrix->a, - pGlyphMatrix->b, - pGlyphMatrix->c, - pGlyphMatrix->d, - pGlyphMatrix->e, - pGlyphMatrix->f); - if (_foxitDevice2User.d < 0) { - glyph_matrix = CGAffineTransformInvert(glyph_matrix); - } - CGContextConcatCTM(_context, glyph_matrix); - CGContextTranslateCTM(_context, -origin.x, -origin.y); + } + if (pBitmap->GetBPP() < 32) { + pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); + } else { + if (pBitmap->GetBuffer()) { + pBitmap1 = (CFX_DIBitmap*)pBitmap; + } else { + pBitmap1 = pBitmap->Clone(); } - CGContextShowGlyphsAtPositions(_context, - (CGGlyph*)glyph_indices, - glyph_positions, - nChars); + } + 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++) { + 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(_context, rect, image); + CGImageRelease(image); + CGContextRelease(ctx); + if (pBitmap1 != pBitmap) { + delete pBitmap1; + } + RestoreState(FALSE); + return TRUE; +} +FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun( + int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pGlyphMatrix, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD argb, + int alpha_flag, + void* pIccTransform) { + if (nChars == 0) { return TRUE; + } + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + if (!pFont->m_pPlatformFont) { + if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { + return FALSE; + } + pFont->m_pPlatformFont = + quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize); + if (NULL == pFont->m_pPlatformFont) { + return FALSE; + } + } + CFX_FixedBufGrow<FX_WORD, 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_AffineMatrix 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, _foxitDevice2User); + CGContextSetTextMatrix(_context, matrix_cg); + CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont); + CGContextSetFontSize(_context, FXSYS_fabs(font_size)); + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBFillColor(_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(_context, origin.x, origin.y); + CGAffineTransform glyph_matrix = CGAffineTransformMake( + pGlyphMatrix->a, pGlyphMatrix->b, pGlyphMatrix->c, pGlyphMatrix->d, + pGlyphMatrix->e, pGlyphMatrix->f); + if (_foxitDevice2User.d < 0) { + glyph_matrix = CGAffineTransformInvert(glyph_matrix); + } + CGContextConcatCTM(_context, glyph_matrix); + CGContextTranslateCTM(_context, -origin.x, -origin.y); + } + CGContextShowGlyphsAtPositions(_context, (CGGlyph*)glyph_indices, + glyph_positions, nChars); + RestoreState(FALSE); + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(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) -{ - if (NULL == pFont || NULL == _context) { - return FALSE; - } - FX_BOOL bBold = pFont->IsBold(); - if (!bBold && pFont->GetSubstFont() && - pFont->GetSubstFont()->m_Weight >= 500 && - pFont->GetSubstFont()->m_Weight <= 600) { - return FALSE; - } - SaveState(); - CGContextSetTextDrawingMode(_context, kCGTextFillClip); - FX_BOOL ret = FALSE; - int32_t i = 0; - while (i < nChars) { - if (pCharPos[i].m_bGlyphAdjust || font_size < 0) { - if (i > 0) { - ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform); - if (!ret) { - RestoreState(FALSE); - return ret; - } - } - const FXTEXT_CHARPOS* char_pos = pCharPos + i; - CFX_AffineMatrix 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_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix, pObject2Device, font_size, color, alpha_flag, pIccTransform); - if (!ret) { - RestoreState(FALSE); - return ret; - } - i ++; - pCharPos += i; - nChars -= i; - i = 0; - } else { - i ++; +FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText( + 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) { + if (NULL == pFont || NULL == _context) { + return FALSE; + } + FX_BOOL bBold = pFont->IsBold(); + if (!bBold && pFont->GetSubstFont() && + pFont->GetSubstFont()->m_Weight >= 500 && + pFont->GetSubstFont()->m_Weight <= 600) { + return FALSE; + } + SaveState(); + CGContextSetTextDrawingMode(_context, kCGTextFillClip); + FX_BOOL ret = FALSE; + int32_t i = 0; + while (i < nChars) { + if (pCharPos[i].m_bGlyphAdjust || font_size < 0) { + if (i > 0) { + ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, + font_size, color, alpha_flag, pIccTransform); + if (!ret) { + RestoreState(FALSE); + return ret; } - } - if (i > 0) { - ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform); - } - RestoreState(FALSE); - return ret; + } + const FXTEXT_CHARPOS* char_pos = pCharPos + i; + CFX_AffineMatrix 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_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix, + pObject2Device, font_size, color, alpha_flag, + pIccTransform); + if (!ret) { + RestoreState(FALSE); + return ret; + } + i++; + pCharPos += i; + nChars -= i; + i = 0; + } else { + i++; + } + } + if (i > 0) { + ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, + font_size, color, alpha_flag, pIccTransform); + } + RestoreState(FALSE); + return ret; } -void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, FX_ARGB argb, FX_FLOAT lineWidth) -{ - if (NULL == graphState) { - return; - } - CGContextSetLineWidth(_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; - } +void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, + FX_ARGB argb, + FX_FLOAT lineWidth) { + if (NULL == graphState) { + return; + } + CGContextSetLineWidth(_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(_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(_context, join); + if (graphState->m_DashCount) { +#if CGFLOAT_IS_DOUBLE + CGFloat* dashArray = new CGFloat[graphState->m_DashCount]; + if (!dashArray) { + return; } - CGContextSetLineCap(_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; - } + for (int index = 0; index < graphState->m_DashCount; ++index) { + dashArray[index] = graphState->m_DashArray[index]; } - CGContextSetLineJoin(_context, join); - if (graphState->m_DashCount) { -#if CGFLOAT_IS_DOUBLE - CGFloat* dashArray = new CGFloat[graphState->m_DashCount]; - if (!dashArray) { - return; - } - for (int index = 0; index < graphState->m_DashCount; ++index) { - dashArray[index] = graphState->m_DashArray[index]; - } #else - CGFloat* dashArray = (CGFloat*)graphState->m_DashArray; + CGFloat* dashArray = (CGFloat*)graphState->m_DashArray; #endif - CGContextSetLineDash(_context, graphState->m_DashPhase, dashArray, graphState->m_DashCount); + CGContextSetLineDash(_context, graphState->m_DashPhase, dashArray, + graphState->m_DashCount); #if CGFLOAT_IS_DOUBLE - delete[] dashArray; + delete[] dashArray; #endif - } - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBStrokeColor(_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(_context, - r / 255.f, - g / 255.f, - b / 255.f, + } + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBStrokeColor(_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(_context); - for (int32_t i = 0; i < count; i ++) { - switch (points[i].m_Flag & FXPT_TYPE) { - case FXPT_MOVETO: - CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_PointY); - break; - case FXPT_LINETO: - CGContextAddLineToPoint(_context, points[i].m_PointX, points[i].m_PointY); - break; - case FXPT_BEZIERTO: { - CGContextAddCurveToPoint(_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(_context); - } - } +void CFX_QuartzDeviceDriver::setFillInfo(FX_ARGB argb) { + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBFillColor(_context, r / 255.f, g / 255.f, b / 255.f, + a / 255.f); } -void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height, - CGRect* rect ) -{ - int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1; - int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1; - if (flip_y < 0 || flip_x < 0) { - if (dest_height < 0) { - dest_height = -dest_height; - dest_top -= dest_height; - } - CGRect rt = CGRectApplyAffineTransform(CGRectMake(dest_left, dest_top, dest_width, dest_height), _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(_context, transform); - if (rect) { - *rect = CGRectApplyAffineTransform(*rect, transform); - } - } +void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData) { + int32_t count = pathData->GetPointCount(); + FX_PATHPOINT* points = pathData->GetPoints(); + CGContextBeginPath(_context); + for (int32_t i = 0; i < count; i++) { + switch (points[i].m_Flag & FXPT_TYPE) { + case FXPT_MOVETO: + CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_PointY); + break; + case FXPT_LINETO: + CGContextAddLineToPoint(_context, points[i].m_PointX, + points[i].m_PointY); + break; + case FXPT_BEZIERTO: { + CGContextAddCurveToPoint(_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(_context); + } + } } -void CFX_QuartzDeviceDriver::ClearDriver() -{ - if (NULL == _context) { - return; - } - for (int i = 0; i < m_saveCount; ++i) { - CGContextRestoreGState(_context); - } - m_saveCount = 0; - if (_context) { - CGContextRelease(_context); - } +void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, + int dest_top, + int dest_width, + int dest_height, + CGRect* rect) { + int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1; + int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1; + if (flip_y < 0 || flip_x < 0) { + if (dest_height < 0) { + dest_height = -dest_height; + dest_top -= dest_height; + } + CGRect rt = CGRectApplyAffineTransform( + CGRectMake(dest_left, dest_top, dest_width, dest_height), + _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(_context, transform); + if (rect) { + *rect = CGRectApplyAffineTransform(*rect, transform); + } + } } -CFX_QuartzDevice::CFX_QuartzDevice() -{ - m_bOwnedBitmap = FALSE; - m_pContext = NULL; +void CFX_QuartzDeviceDriver::ClearDriver() { + if (NULL == _context) { + return; + } + for (int i = 0; i < m_saveCount; ++i) { + CGContextRestoreGState(_context); + } + m_saveCount = 0; + if (_context) { + CGContextRelease(_context); + } } -CFX_QuartzDevice::~CFX_QuartzDevice() -{ - if (m_pContext) { - CGContextRelease(m_pContext); - } - if (m_bOwnedBitmap) { - delete GetBitmap(); - } +CFX_QuartzDevice::CFX_QuartzDevice() { + m_bOwnedBitmap = FALSE; + m_pContext = NULL; } -CGContextRef CFX_QuartzDevice::GetContext() -{ - return m_pContext; +CFX_QuartzDevice::~CFX_QuartzDevice() { + if (m_pContext) { + CGContextRelease(m_pContext); + } + if (m_bOwnedBitmap) { + delete GetBitmap(); + } } -FX_BOOL CFX_QuartzDevice::Attach(CGContextRef context, int32_t nDeviceClass) -{ - if (m_pContext) { - CGContextRelease(m_pContext); - } - m_pContext = context; - CGContextRetain(m_pContext); - IFX_RenderDeviceDriver* pDriver = FX_NEW CFX_QuartzDeviceDriver(m_pContext, nDeviceClass); - if (!pDriver) { - return FALSE; - } - SetDeviceDriver(pDriver); - return TRUE; +CGContextRef CFX_QuartzDevice::GetContext() { + return m_pContext; } -FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap) -{ - SetBitmap(pBitmap); - m_pContext = createContextWithBitmap(pBitmap); - if (NULL == m_pContext) { - return FALSE; - } - IFX_RenderDeviceDriver* pDriver = FX_NEW CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY); - if (!pDriver) { - return FALSE; - } - SetDeviceDriver(pDriver); - return TRUE; +FX_BOOL CFX_QuartzDevice::Attach(CGContextRef context, int32_t nDeviceClass) { + if (m_pContext) { + CGContextRelease(m_pContext); + } + m_pContext = context; + CGContextRetain(m_pContext); + IFX_RenderDeviceDriver* pDriver = + FX_NEW CFX_QuartzDeviceDriver(m_pContext, nDeviceClass); + if (!pDriver) { + return FALSE; + } + SetDeviceDriver(pDriver); + return TRUE; } -FX_BOOL CFX_QuartzDevice::Create(int32_t width, int32_t height, FXDIB_Format format) -{ - if ((uint8_t)format < 32) { - return FALSE; - } - CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap; - if (!pBitmap) { - return FALSE; - } - if (!pBitmap->Create(width, height, format)) { - delete pBitmap; - return FALSE; - } - m_bOwnedBitmap = TRUE; - return Attach(pBitmap); +FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap) { + SetBitmap(pBitmap); + m_pContext = createContextWithBitmap(pBitmap); + if (NULL == m_pContext) { + return FALSE; + } + IFX_RenderDeviceDriver* pDriver = + FX_NEW CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY); + if (!pDriver) { + return FALSE; + } + SetDeviceDriver(pDriver); + return TRUE; +} +FX_BOOL CFX_QuartzDevice::Create(int32_t width, + int32_t height, + FXDIB_Format format) { + if ((uint8_t)format < 32) { + return FALSE; + } + CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap; + if (!pBitmap) { + return FALSE; + } + if (!pBitmap->Create(width, height, format)) { + delete pBitmap; + return FALSE; + } + m_bOwnedBitmap = TRUE; + return Attach(pBitmap); } #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |