| Index: core/src/fxge/apple/fx_quartz_device.cpp | 
| diff --git a/core/src/fxge/apple/fx_quartz_device.cpp b/core/src/fxge/apple/fx_quartz_device.cpp | 
| index d1e4f544ba85f3a4da9db18d7a6280b2a5ed0951..34851e0c80bfae977eff82a47fef760662264d07 100644 | 
| --- a/core/src/fxge/apple/fx_quartz_device.cpp | 
| +++ b/core/src/fxge/apple/fx_quartz_device.cpp | 
| @@ -11,1118 +11,1046 @@ | 
| #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() { | 
| +  CGContextSaveGState(_context); | 
| +  m_saveCount++; | 
| } | 
| -void CFX_QuartzDeviceDriver::SaveState() | 
| -{ | 
| +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 = new CFX_QuartzDeviceDriver(m_pContext, nDeviceClass); | 
| -    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 = new CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY); | 
| -    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 = | 
| +      new CFX_QuartzDeviceDriver(m_pContext, nDeviceClass); | 
| +  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 = new CFX_DIBitmap; | 
| -    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 = | 
| +      new CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY); | 
| +  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 = new CFX_DIBitmap; | 
| +  if (!pBitmap->Create(width, height, format)) { | 
| +    delete pBitmap; | 
| +    return FALSE; | 
| +  } | 
| +  m_bOwnedBitmap = TRUE; | 
| +  return Attach(pBitmap); | 
| } | 
| #endif  // _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_ | 
|  |