| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/fxcrt/include/fx_ext.h" | 7 #include "core/fxcrt/include/fx_ext.h" |
| 8 | 8 |
| 9 #ifndef _SKIA_SUPPORT_ | 9 #ifndef _SKIA_SUPPORT_ |
| 10 #include "core/fxge/agg/fx_agg_driver.h" | 10 #include "core/fxge/agg/fx_agg_driver.h" |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 break; | 333 break; |
| 334 case FXDIB_BLEND_LUMINOSITY: | 334 case FXDIB_BLEND_LUMINOSITY: |
| 335 mode = kCGBlendModeLuminosity; | 335 mode = kCGBlendModeLuminosity; |
| 336 break; | 336 break; |
| 337 default: | 337 default: |
| 338 mode = kCGBlendModeNormal; | 338 mode = kCGBlendModeNormal; |
| 339 break; | 339 break; |
| 340 } | 340 } |
| 341 return mode; | 341 return mode; |
| 342 } | 342 } |
| 343 |
| 343 FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData, | 344 FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData, |
| 344 const CFX_Matrix* matrix, | 345 const CFX_Matrix* matrix, |
| 345 const CFX_GraphStateData* graphState, | 346 const CFX_GraphStateData* graphState, |
| 346 uint32_t fillArgb, | 347 uint32_t fillArgb, |
| 347 uint32_t strokeArgb, | 348 uint32_t strokeArgb, |
| 348 int fillMode, | 349 int fillMode, |
| 349 int alpha_flag, | |
| 350 void* pIccTransform, | |
| 351 int blend_type) { | 350 int blend_type) { |
| 352 SaveState(); | 351 SaveState(); |
| 353 CGBlendMode mode = GetCGBlendMode(blend_type); | 352 CGBlendMode mode = GetCGBlendMode(blend_type); |
| 354 if (mode != kCGBlendModeNormal) { | 353 if (mode != kCGBlendModeNormal) { |
| 355 CGContextSetBlendMode(m_context, mode); | 354 CGContextSetBlendMode(m_context, mode); |
| 356 } | 355 } |
| 357 CGAffineTransform m = CGAffineTransformIdentity; | 356 CGAffineTransform m = CGAffineTransformIdentity; |
| 358 if (matrix) { | 357 if (matrix) { |
| 359 m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), | 358 m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), |
| 360 matrix->GetD(), matrix->GetE(), matrix->GetF()); | 359 matrix->GetD(), matrix->GetE(), matrix->GetF()); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 387 } else if (pathMode == 2) { | 386 } else if (pathMode == 2) { |
| 388 CGContextEOFillPath(m_context); | 387 CGContextEOFillPath(m_context); |
| 389 } else if (pathMode == 5) { | 388 } else if (pathMode == 5) { |
| 390 CGContextDrawPath(m_context, kCGPathFillStroke); | 389 CGContextDrawPath(m_context, kCGPathFillStroke); |
| 391 } else if (pathMode == 6) { | 390 } else if (pathMode == 6) { |
| 392 CGContextDrawPath(m_context, kCGPathEOFillStroke); | 391 CGContextDrawPath(m_context, kCGPathEOFillStroke); |
| 393 } | 392 } |
| 394 RestoreState(false); | 393 RestoreState(false); |
| 395 return TRUE; | 394 return TRUE; |
| 396 } | 395 } |
| 397 FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect, | 396 |
| 398 FX_ARGB fillArgb, | 397 FX_BOOL CFX_QuartzDeviceDriver::FillRectWithBlend(const FX_RECT* rect, |
| 399 int alphaFlag, | 398 FX_ARGB fillArgb, |
| 400 void* iccTransform, | 399 int blend_type) { |
| 401 int blend_type) { | |
| 402 CGBlendMode mode = GetCGBlendMode(blend_type); | 400 CGBlendMode mode = GetCGBlendMode(blend_type); |
| 403 if (mode != kCGBlendModeNormal) { | 401 if (mode != kCGBlendModeNormal) { |
| 404 CGContextSetBlendMode(m_context, mode); | 402 CGContextSetBlendMode(m_context, mode); |
| 405 } | 403 } |
| 406 CGRect rect_fx = | 404 CGRect rect_fx = |
| 407 CGRectMake(rect->left, rect->top, rect->Width(), rect->Height()); | 405 CGRectMake(rect->left, rect->top, rect->Width(), rect->Height()); |
| 408 CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, m_foxitDevice2User); | 406 CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, m_foxitDevice2User); |
| 409 int32_t a, r, g, b; | 407 int32_t a, r, g, b; |
| 410 ArgbDecode(fillArgb, a, r, g, b); | 408 ArgbDecode(fillArgb, a, r, g, b); |
| 411 CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f, | 409 CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f, |
| 412 a / 255.f); | 410 a / 255.f); |
| 413 CGContextFillRect(m_context, rect_usr); | 411 CGContextFillRect(m_context, rect_usr); |
| 414 if (mode != kCGBlendModeNormal) { | 412 if (mode != kCGBlendModeNormal) { |
| 415 CGContextSetBlendMode(m_context, kCGBlendModeNormal); | 413 CGContextSetBlendMode(m_context, kCGBlendModeNormal); |
| 416 } | 414 } |
| 417 return TRUE; | 415 return TRUE; |
| 418 } | 416 } |
| 417 |
| 419 FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, | 418 FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, |
| 420 FX_FLOAT y1, | 419 FX_FLOAT y1, |
| 421 FX_FLOAT x2, | 420 FX_FLOAT x2, |
| 422 FX_FLOAT y2, | 421 FX_FLOAT y2, |
| 423 uint32_t argb, | 422 uint32_t argb, |
| 424 int alphaFlag, | |
| 425 void* iccTransform, | |
| 426 int blend_type) { | 423 int blend_type) { |
| 427 CGBlendMode mode = GetCGBlendMode(blend_type); | 424 CGBlendMode mode = GetCGBlendMode(blend_type); |
| 428 if (mode != kCGBlendModeNormal) { | 425 if (mode != kCGBlendModeNormal) { |
| 429 CGContextSetBlendMode(m_context, mode); | 426 CGContextSetBlendMode(m_context, mode); |
| 430 } | 427 } |
| 431 CGPoint pt = | 428 CGPoint pt = |
| 432 CGPointApplyAffineTransform(CGPointMake(x1, y1), m_foxitDevice2User); | 429 CGPointApplyAffineTransform(CGPointMake(x1, y1), m_foxitDevice2User); |
| 433 x1 = pt.x; | 430 x1 = pt.x; |
| 434 y1 = pt.y; | 431 y1 = pt.y; |
| 435 pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), m_foxitDevice2User); | 432 pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), m_foxitDevice2User); |
| 436 x2 = pt.x; | 433 x2 = pt.x; |
| 437 y2 = pt.y; | 434 y2 = pt.y; |
| 438 int32_t a, r, g, b; | 435 int32_t a, r, g, b; |
| 439 ArgbDecode(argb, a, r, g, b); | 436 ArgbDecode(argb, a, r, g, b); |
| 440 CGContextSetRGBStrokeColor(m_context, r / 255.f, g / 255.f, b / 255.f, | 437 CGContextSetRGBStrokeColor(m_context, r / 255.f, g / 255.f, b / 255.f, |
| 441 a / 255.f); | 438 a / 255.f); |
| 442 CGContextMoveToPoint(m_context, x1, y1); | 439 CGContextMoveToPoint(m_context, x1, y1); |
| 443 CGContextAddLineToPoint(m_context, x2, y2); | 440 CGContextAddLineToPoint(m_context, x2, y2); |
| 444 CGContextStrokePath(m_context); | 441 CGContextStrokePath(m_context); |
| 445 if (mode != kCGBlendModeNormal) { | 442 if (mode != kCGBlendModeNormal) { |
| 446 CGContextSetBlendMode(m_context, kCGBlendModeNormal); | 443 CGContextSetBlendMode(m_context, kCGBlendModeNormal); |
| 447 } | 444 } |
| 448 return TRUE; | 445 return TRUE; |
| 449 } | 446 } |
| 447 |
| 450 FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) { | 448 FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) { |
| 451 CGRect r = CGContextGetClipBoundingBox(m_context); | 449 CGRect r = CGContextGetClipBoundingBox(m_context); |
| 452 r = CGRectApplyAffineTransform(r, m_user2FoxitDevice); | 450 r = CGRectApplyAffineTransform(r, m_user2FoxitDevice); |
| 453 rect->left = FXSYS_floor(r.origin.x); | 451 rect->left = FXSYS_floor(r.origin.x); |
| 454 rect->top = FXSYS_floor(r.origin.y); | 452 rect->top = FXSYS_floor(r.origin.y); |
| 455 rect->right = FXSYS_ceil(r.origin.x + r.size.width); | 453 rect->right = FXSYS_ceil(r.origin.x + r.size.width); |
| 456 rect->bottom = FXSYS_ceil(r.origin.y + r.size.height); | 454 rect->bottom = FXSYS_ceil(r.origin.y + r.size.height); |
| 457 return TRUE; | 455 return TRUE; |
| 458 } | 456 } |
| 457 |
| 459 FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap, | 458 FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap, |
| 460 int32_t left, | 459 int32_t left, |
| 461 int32_t top, | 460 int32_t top) { |
| 462 void* pIccTransform, | 461 if (FXDC_PRINTER == m_deviceClass || bitmap->GetBPP() < 32 || |
| 463 FX_BOOL bDEdge) { | 462 !(m_renderCaps | FXRC_GET_BITS)) { |
| 464 if (FXDC_PRINTER == m_deviceClass) { | |
| 465 return FALSE; | 463 return FALSE; |
| 466 } | 464 } |
| 467 if (bitmap->GetBPP() < 32) { | 465 |
| 468 return FALSE; | |
| 469 } | |
| 470 if (!(m_renderCaps | FXRC_GET_BITS)) { | |
| 471 return FALSE; | |
| 472 } | |
| 473 CGPoint pt = CGPointMake(left, top); | 466 CGPoint pt = CGPointMake(left, top); |
| 474 pt = CGPointApplyAffineTransform(pt, m_foxitDevice2User); | 467 pt = CGPointApplyAffineTransform(pt, m_foxitDevice2User); |
| 475 CGAffineTransform ctm = CGContextGetCTM(m_context); | 468 CGAffineTransform ctm = CGContextGetCTM(m_context); |
| 476 pt.x *= FXSYS_fabs(ctm.a); | 469 pt.x *= FXSYS_fabs(ctm.a); |
| 477 pt.y *= FXSYS_fabs(ctm.d); | 470 pt.y *= FXSYS_fabs(ctm.d); |
| 478 CGImageRef image = CGBitmapContextCreateImage(m_context); | 471 CGImageRef image = CGBitmapContextCreateImage(m_context); |
| 479 if (!image) | 472 if (!image) |
| 480 return FALSE; | 473 return FALSE; |
| 481 | 474 |
| 482 CGFloat width = (CGFloat)bitmap->GetWidth(); | 475 CGFloat width = (CGFloat)bitmap->GetWidth(); |
| 483 CGFloat height = (CGFloat)bitmap->GetHeight(); | 476 CGFloat height = (CGFloat)bitmap->GetHeight(); |
| 484 if (width + pt.x > m_width) { | 477 if (width + pt.x > m_width) |
| 485 width -= (width + pt.x - m_width); | 478 width -= (width + pt.x - m_width); |
| 486 } | 479 if (height + pt.y > m_height) |
| 487 if (height + pt.y > m_height) { | |
| 488 height -= (height + pt.y - m_height); | 480 height -= (height + pt.y - m_height); |
| 489 } | 481 |
| 490 CGImageRef subImage = CGImageCreateWithImageInRect( | 482 CGImageRef subImage = CGImageCreateWithImageInRect( |
| 491 image, CGRectMake(pt.x, pt.y, width, height)); | 483 image, CGRectMake(pt.x, pt.y, width, height)); |
| 492 CGContextRef context = createContextWithBitmap(bitmap); | 484 CGContextRef context = createContextWithBitmap(bitmap); |
| 493 CGRect rect = CGContextGetClipBoundingBox(context); | 485 CGRect rect = CGContextGetClipBoundingBox(context); |
| 494 CGContextClearRect(context, rect); | 486 CGContextClearRect(context, rect); |
| 495 CGContextDrawImage(context, rect, subImage); | 487 CGContextDrawImage(context, rect, subImage); |
| 496 CGContextRelease(context); | 488 CGContextRelease(context); |
| 497 CGImageRelease(subImage); | 489 CGImageRelease(subImage); |
| 498 CGImageRelease(image); | 490 CGImageRelease(image); |
| 499 if (bitmap->HasAlpha()) { | 491 if (!bitmap->HasAlpha()) |
| 500 for (int row = 0; row < bitmap->GetHeight(); row++) { | 492 return TRUE; |
| 501 uint8_t* pScanline = (uint8_t*)bitmap->GetScanline(row); | 493 |
| 502 for (int col = 0; col < bitmap->GetWidth(); col++) { | 494 for (int row = 0; row < bitmap->GetHeight(); row++) { |
| 503 if (pScanline[3] > 0) { | 495 uint8_t* pScanline = (uint8_t*)bitmap->GetScanline(row); |
| 504 pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f); | 496 for (int col = 0; col < bitmap->GetWidth(); col++) { |
| 505 pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f); | 497 if (pScanline[3] > 0) { |
| 506 pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f); | 498 pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f); |
| 507 } | 499 pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f); |
| 508 pScanline += 4; | 500 pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f); |
| 509 } | 501 } |
| 502 pScanline += 4; |
| 510 } | 503 } |
| 511 } | 504 } |
| 512 return TRUE; | 505 return TRUE; |
| 513 } | 506 } |
| 507 |
| 514 FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, | 508 FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, |
| 515 FX_ARGB argb, | 509 FX_ARGB argb, |
| 516 const FX_RECT* srcRect, | 510 const FX_RECT* srcRect, |
| 517 int dest_left, | 511 int dest_left, |
| 518 int dest_top, | 512 int dest_top, |
| 519 int blendType, | 513 int blendType) { |
| 520 int alphaFlag, | |
| 521 void* iccTransform) { | |
| 522 SaveState(); | 514 SaveState(); |
| 523 CGFloat src_left, src_top, src_width, src_height; | 515 CGFloat src_left, src_top, src_width, src_height; |
| 524 if (srcRect) { | 516 if (srcRect) { |
| 525 src_left = srcRect->left; | 517 src_left = srcRect->left; |
| 526 src_top = srcRect->top; | 518 src_top = srcRect->top; |
| 527 src_width = srcRect->Width(); | 519 src_width = srcRect->Width(); |
| 528 src_height = srcRect->Height(); | 520 src_height = srcRect->Height(); |
| 529 } else { | 521 } else { |
| 530 src_left = src_top = 0; | 522 src_left = src_top = 0; |
| 531 src_width = pBitmap->GetWidth(); | 523 src_width = pBitmap->GetWidth(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 CGContextSetBlendMode(m_context, (CGBlendMode)blend_mode); | 620 CGContextSetBlendMode(m_context, (CGBlendMode)blend_mode); |
| 629 CGContextDrawImage(m_context, rect_usr, image); | 621 CGContextDrawImage(m_context, rect_usr, image); |
| 630 CGImageRelease(image); | 622 CGImageRelease(image); |
| 631 CGContextRelease(ctx); | 623 CGContextRelease(ctx); |
| 632 if (pBitmap1 != pBitmap) { | 624 if (pBitmap1 != pBitmap) { |
| 633 delete pBitmap1; | 625 delete pBitmap1; |
| 634 } | 626 } |
| 635 RestoreState(false); | 627 RestoreState(false); |
| 636 return TRUE; | 628 return TRUE; |
| 637 } | 629 } |
| 630 |
| 638 FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap, | 631 FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap, |
| 639 FX_ARGB argb, | 632 FX_ARGB argb, |
| 640 int dest_left, | 633 int dest_left, |
| 641 int dest_top, | 634 int dest_top, |
| 642 int dest_width, | 635 int dest_width, |
| 643 int dest_height, | 636 int dest_height, |
| 644 const FX_RECT* clipRect, | 637 const FX_RECT* clipRect, |
| 645 uint32_t flags, | 638 uint32_t flags, |
| 646 int alphaFlag, | |
| 647 void* iccTransform, | |
| 648 int blend_type) { | 639 int blend_type) { |
| 649 SaveState(); | 640 SaveState(); |
| 650 if (clipRect) { | 641 if (clipRect) { |
| 651 CGContextBeginPath(m_context); | 642 CGContextBeginPath(m_context); |
| 652 CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, | 643 CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, |
| 653 clipRect->Width(), clipRect->Height()); | 644 clipRect->Width(), clipRect->Height()); |
| 654 rect_clip = CGRectApplyAffineTransform(rect_clip, m_foxitDevice2User); | 645 rect_clip = CGRectApplyAffineTransform(rect_clip, m_foxitDevice2User); |
| 655 CGContextAddRect(m_context, rect_clip); | 646 CGContextAddRect(m_context, rect_clip); |
| 656 CGContextClip(m_context); | 647 CGContextClip(m_context); |
| 657 } | 648 } |
| 658 CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height); | 649 CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height); |
| 659 rect = CGRectApplyAffineTransform(rect, m_foxitDevice2User); | 650 rect = CGRectApplyAffineTransform(rect, m_foxitDevice2User); |
| 660 if (FXDIB_BICUBIC_INTERPOL == flags) { | 651 if (FXDIB_BICUBIC_INTERPOL == flags) |
| 661 CGContextSetInterpolationQuality(m_context, kCGInterpolationHigh); | 652 CGContextSetInterpolationQuality(m_context, kCGInterpolationHigh); |
| 662 } else if (FXDIB_DOWNSAMPLE == flags) { | 653 else if (FXDIB_DOWNSAMPLE == flags) |
| 663 CGContextSetInterpolationQuality(m_context, kCGInterpolationNone); | 654 CGContextSetInterpolationQuality(m_context, kCGInterpolationNone); |
| 664 } else { | 655 else |
| 665 CGContextSetInterpolationQuality(m_context, kCGInterpolationMedium); | 656 CGContextSetInterpolationQuality(m_context, kCGInterpolationMedium); |
| 666 } | 657 |
| 667 CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height); | 658 CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height, nullptr); |
| 668 CFX_DIBitmap* pBitmap1 = nullptr; | 659 CFX_DIBitmap* pBitmap1 = nullptr; |
| 669 if (pBitmap->IsAlphaMask()) { | 660 if (pBitmap->IsAlphaMask()) { |
| 670 if (pBitmap->GetBuffer()) { | 661 if (pBitmap->GetBuffer()) |
| 671 pBitmap1 = (CFX_DIBitmap*)pBitmap; | 662 pBitmap1 = (CFX_DIBitmap*)pBitmap; |
| 672 } else { | 663 else |
| 673 pBitmap1 = pBitmap->Clone(); | 664 pBitmap1 = pBitmap->Clone(); |
| 674 } | |
| 675 if (!pBitmap1) { | 665 if (!pBitmap1) { |
| 676 RestoreState(false); | 666 RestoreState(false); |
| 677 return FALSE; | 667 return FALSE; |
| 678 } | 668 } |
| 679 CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData( | 669 CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData( |
| 680 nullptr, pBitmap1->GetBuffer(), | 670 nullptr, pBitmap1->GetBuffer(), |
| 681 pBitmap1->GetPitch() * pBitmap1->GetHeight(), nullptr); | 671 pBitmap1->GetPitch() * pBitmap1->GetHeight(), nullptr); |
| 682 CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); | 672 CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); |
| 683 CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; | 673 CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; |
| 684 CGImageRef pImage = CGImageCreate( | 674 CGImageRef pImage = CGImageCreate( |
| 685 pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), | 675 pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), |
| 686 pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, | 676 pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, |
| 687 pBitmapProvider, nullptr, true, kCGRenderingIntentDefault); | 677 pBitmapProvider, nullptr, true, kCGRenderingIntentDefault); |
| 688 CGContextClipToMask(m_context, rect, pImage); | 678 CGContextClipToMask(m_context, rect, pImage); |
| 689 CGContextSetRGBFillColor(m_context, FXARGB_R(argb) / 255.f, | 679 CGContextSetRGBFillColor(m_context, FXARGB_R(argb) / 255.f, |
| 690 FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, | 680 FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, |
| 691 FXARGB_A(argb) / 255.f); | 681 FXARGB_A(argb) / 255.f); |
| 692 CGContextFillRect(m_context, rect); | 682 CGContextFillRect(m_context, rect); |
| 693 CGImageRelease(pImage); | 683 CGImageRelease(pImage); |
| 694 CGColorSpaceRelease(pColorSpace); | 684 CGColorSpaceRelease(pColorSpace); |
| 695 CGDataProviderRelease(pBitmapProvider); | 685 CGDataProviderRelease(pBitmapProvider); |
| 696 if (pBitmap1 != pBitmap) { | 686 if (pBitmap1 != pBitmap) |
| 697 delete pBitmap1; | 687 delete pBitmap1; |
| 698 } | 688 |
| 699 RestoreState(false); | 689 RestoreState(false); |
| 700 return TRUE; | 690 return TRUE; |
| 701 } | 691 } |
| 702 if (pBitmap->GetBPP() < 32) { | 692 if (pBitmap->GetBPP() < 32) { |
| 703 pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); | 693 pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); |
| 704 } else { | 694 } else { |
| 705 if (pBitmap->GetBuffer()) { | 695 if (pBitmap->GetBuffer()) |
| 706 pBitmap1 = (CFX_DIBitmap*)pBitmap; | 696 pBitmap1 = (CFX_DIBitmap*)pBitmap; |
| 707 } else { | 697 else |
| 708 pBitmap1 = pBitmap->Clone(); | 698 pBitmap1 = pBitmap->Clone(); |
| 709 } | |
| 710 } | 699 } |
| 711 if (!pBitmap1) { | 700 if (!pBitmap1) { |
| 712 RestoreState(false); | 701 RestoreState(false); |
| 713 return FALSE; | 702 return FALSE; |
| 714 } | 703 } |
| 715 if (pBitmap1->HasAlpha()) { | 704 if (pBitmap1->HasAlpha()) { |
| 716 if (pBitmap1 == pBitmap) { | 705 if (pBitmap1 == pBitmap) { |
| 717 pBitmap1 = pBitmap->Clone(); | 706 pBitmap1 = pBitmap->Clone(); |
| 718 if (!pBitmap1) { | 707 if (!pBitmap1) { |
| 719 RestoreState(false); | 708 RestoreState(false); |
| 720 return FALSE; | 709 return FALSE; |
| 721 } | 710 } |
| 722 } | 711 } |
| 723 for (int row = 0; row < pBitmap1->GetHeight(); row++) { | 712 for (int row = 0; row < pBitmap1->GetHeight(); row++) { |
| 724 uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row); | 713 uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row); |
| 725 for (int col = 0; col < pBitmap1->GetWidth(); col++) { | 714 for (int col = 0; col < pBitmap1->GetWidth(); col++) { |
| 726 pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f); | 715 pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f); |
| 727 pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f); | 716 pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f); |
| 728 pScanline[2] = (uint8_t)(pScanline[2] * pScanline[3] / 255.f + .5f); | 717 pScanline[2] = (uint8_t)(pScanline[2] * pScanline[3] / 255.f + .5f); |
| 729 pScanline += 4; | 718 pScanline += 4; |
| 730 } | 719 } |
| 731 } | 720 } |
| 732 } | 721 } |
| 733 CGContextRef ctx = createContextWithBitmap(pBitmap1); | 722 CGContextRef ctx = createContextWithBitmap(pBitmap1); |
| 734 CGImageRef image = CGBitmapContextCreateImage(ctx); | 723 CGImageRef image = CGBitmapContextCreateImage(ctx); |
| 735 CGContextDrawImage(m_context, rect, image); | 724 CGContextDrawImage(m_context, rect, image); |
| 736 CGImageRelease(image); | 725 CGImageRelease(image); |
| 737 CGContextRelease(ctx); | 726 CGContextRelease(ctx); |
| 738 if (pBitmap1 != pBitmap) { | 727 if (pBitmap1 != pBitmap) |
| 739 delete pBitmap1; | 728 delete pBitmap1; |
| 740 } | 729 |
| 741 RestoreState(false); | 730 RestoreState(false); |
| 742 return TRUE; | 731 return TRUE; |
| 743 } | 732 } |
| 744 FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun(int nChars, | 733 |
| 745 const FXTEXT_CHARPOS* pCharPos, | 734 FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlyphRun( |
| 746 CFX_Font* pFont, | 735 int nChars, |
| 747 CFX_FontCache* pCache, | 736 const FXTEXT_CHARPOS* pCharPos, |
| 748 const CFX_Matrix* pGlyphMatrix, | 737 CFX_Font* pFont, |
| 749 const CFX_Matrix* pObject2Device, | 738 CFX_FontCache* pCache, |
| 750 FX_FLOAT font_size, | 739 const CFX_Matrix* pGlyphMatrix, |
| 751 uint32_t argb, | 740 const CFX_Matrix* pObject2Device, |
| 752 int alpha_flag, | 741 FX_FLOAT font_size, |
| 753 void* pIccTransform) { | 742 uint32_t argb) { |
| 754 if (nChars == 0) { | 743 if (nChars == 0) |
| 755 return TRUE; | 744 return TRUE; |
| 756 } | 745 |
| 757 CQuartz2D& quartz2d = | 746 CQuartz2D& quartz2d = |
| 758 static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData()) | 747 static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData()) |
| 759 ->m_quartz2d; | 748 ->m_quartz2d; |
| 760 if (!pFont->GetPlatformFont()) { | 749 if (!pFont->GetPlatformFont()) { |
| 761 if (pFont->GetPsName() == "DFHeiStd-W5") | 750 if (pFont->GetPsName() == "DFHeiStd-W5") |
| 762 return FALSE; | 751 return FALSE; |
| 763 | 752 |
| 764 pFont->SetPlatformFont( | 753 pFont->SetPlatformFont( |
| 765 quartz2d.CreateFont(pFont->GetFontData(), pFont->GetSize())); | 754 quartz2d.CreateFont(pFont->GetFontData(), pFont->GetSize())); |
| 766 if (!pFont->GetPlatformFont()) { | 755 if (!pFont->GetPlatformFont()) { |
| 767 return FALSE; | 756 return FALSE; |
| 768 } | 757 } |
| 769 } | 758 } |
| 770 CFX_FixedBufGrow<uint16_t, 32> glyph_indices(nChars); | 759 CFX_FixedBufGrow<uint16_t, 32> glyph_indices(nChars); |
| 771 CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars); | 760 CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars); |
| 772 for (int i = 0; i < nChars; i++) { | 761 for (int i = 0; i < nChars; i++) { |
| 773 glyph_indices[i] = pCharPos[i].m_ExtGID; | 762 glyph_indices[i] = pCharPos[i].m_ExtGID; |
| 774 glyph_positions[i].x = pCharPos[i].m_OriginX; | 763 glyph_positions[i].x = pCharPos[i].m_OriginX; |
| 775 glyph_positions[i].y = pCharPos[i].m_OriginY; | 764 glyph_positions[i].y = pCharPos[i].m_OriginY; |
| 776 } | 765 } |
| 777 CFX_Matrix text_matrix; | 766 CFX_Matrix text_matrix; |
| 778 if (pObject2Device) { | 767 if (pObject2Device) |
| 779 text_matrix.Concat(*pObject2Device); | 768 text_matrix.Concat(*pObject2Device); |
| 780 } | 769 |
| 781 CGAffineTransform matrix_cg = | 770 CGAffineTransform matrix_cg = |
| 782 CGAffineTransformMake(text_matrix.a, text_matrix.b, text_matrix.c, | 771 CGAffineTransformMake(text_matrix.a, text_matrix.b, text_matrix.c, |
| 783 text_matrix.d, text_matrix.e, text_matrix.f); | 772 text_matrix.d, text_matrix.e, text_matrix.f); |
| 784 matrix_cg = CGAffineTransformConcat(matrix_cg, m_foxitDevice2User); | 773 matrix_cg = CGAffineTransformConcat(matrix_cg, m_foxitDevice2User); |
| 785 CGContextSetTextMatrix(m_context, matrix_cg); | 774 CGContextSetTextMatrix(m_context, matrix_cg); |
| 786 CGContextSetFont(m_context, (CGFontRef)pFont->GetPlatformFont()); | 775 CGContextSetFont(m_context, (CGFontRef)pFont->GetPlatformFont()); |
| 787 CGContextSetFontSize(m_context, FXSYS_fabs(font_size)); | 776 CGContextSetFontSize(m_context, FXSYS_fabs(font_size)); |
| 788 int32_t a, r, g, b; | 777 int32_t a, r, g, b; |
| 789 ArgbDecode(argb, a, r, g, b); | 778 ArgbDecode(argb, a, r, g, b); |
| 790 CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f, | 779 CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f, |
| 791 a / 255.f); | 780 a / 255.f); |
| 792 SaveState(); | 781 SaveState(); |
| 793 if (pGlyphMatrix) { | 782 if (pGlyphMatrix) { |
| 794 CGPoint origin = CGPointMake(glyph_positions[0].x, glyph_positions[0].y); | 783 CGPoint origin = CGPointMake(glyph_positions[0].x, glyph_positions[0].y); |
| 795 origin = CGPointApplyAffineTransform(origin, matrix_cg); | 784 origin = CGPointApplyAffineTransform(origin, matrix_cg); |
| 796 CGContextTranslateCTM(m_context, origin.x, origin.y); | 785 CGContextTranslateCTM(m_context, origin.x, origin.y); |
| 797 CGAffineTransform glyph_matrix = CGAffineTransformMake( | 786 CGAffineTransform glyph_matrix = CGAffineTransformMake( |
| 798 pGlyphMatrix->a, pGlyphMatrix->b, pGlyphMatrix->c, pGlyphMatrix->d, | 787 pGlyphMatrix->a, pGlyphMatrix->b, pGlyphMatrix->c, pGlyphMatrix->d, |
| 799 pGlyphMatrix->e, pGlyphMatrix->f); | 788 pGlyphMatrix->e, pGlyphMatrix->f); |
| 800 if (m_foxitDevice2User.d < 0) { | 789 if (m_foxitDevice2User.d < 0) |
| 801 glyph_matrix = CGAffineTransformInvert(glyph_matrix); | 790 glyph_matrix = CGAffineTransformInvert(glyph_matrix); |
| 802 } | 791 |
| 803 CGContextConcatCTM(m_context, glyph_matrix); | 792 CGContextConcatCTM(m_context, glyph_matrix); |
| 804 CGContextTranslateCTM(m_context, -origin.x, -origin.y); | 793 CGContextTranslateCTM(m_context, -origin.x, -origin.y); |
| 805 } | 794 } |
| 806 CGContextShowGlyphsAtPositions(m_context, (CGGlyph*)glyph_indices, | 795 CGContextShowGlyphsAtPositions(m_context, (CGGlyph*)glyph_indices, |
| 807 glyph_positions, nChars); | 796 glyph_positions, nChars); |
| 808 RestoreState(false); | 797 RestoreState(false); |
| 809 return TRUE; | 798 return TRUE; |
| 810 } | 799 } |
| 800 |
| 811 FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(int nChars, | 801 FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(int nChars, |
| 812 const FXTEXT_CHARPOS* pCharPos, | 802 const FXTEXT_CHARPOS* pCharPos, |
| 813 CFX_Font* pFont, | 803 CFX_Font* pFont, |
| 814 CFX_FontCache* pCache, | 804 CFX_FontCache* pCache, |
| 815 const CFX_Matrix* pObject2Device, | 805 const CFX_Matrix* pObject2Device, |
| 816 FX_FLOAT font_size, | 806 FX_FLOAT font_size, |
| 817 uint32_t color, | 807 uint32_t color) { |
| 818 int alpha_flag, | |
| 819 void* pIccTransform) { | |
| 820 if (!pFont || !m_context) | 808 if (!pFont || !m_context) |
| 821 return FALSE; | 809 return FALSE; |
| 810 |
| 822 FX_BOOL bBold = pFont->IsBold(); | 811 FX_BOOL bBold = pFont->IsBold(); |
| 823 if (!bBold && pFont->GetSubstFont() && | 812 if (!bBold && pFont->GetSubstFont() && |
| 824 pFont->GetSubstFont()->m_Weight >= 500 && | 813 pFont->GetSubstFont()->m_Weight >= 500 && |
| 825 pFont->GetSubstFont()->m_Weight <= 600) { | 814 pFont->GetSubstFont()->m_Weight <= 600) { |
| 826 return FALSE; | 815 return FALSE; |
| 827 } | 816 } |
| 828 SaveState(); | 817 SaveState(); |
| 829 CGContextSetTextDrawingMode(m_context, kCGTextFillClip); | 818 CGContextSetTextDrawingMode(m_context, kCGTextFillClip); |
| 830 FX_BOOL ret = FALSE; | 819 FX_BOOL ret = FALSE; |
| 831 int32_t i = 0; | 820 int32_t i = 0; |
| 832 while (i < nChars) { | 821 while (i < nChars) { |
| 833 if (pCharPos[i].m_bGlyphAdjust || font_size < 0) { | 822 if (pCharPos[i].m_bGlyphAdjust || font_size < 0) { |
| 834 if (i > 0) { | 823 if (i > 0) { |
| 835 ret = | 824 ret = CG_DrawGlyphRun(i, pCharPos, pFont, pCache, nullptr, |
| 836 CG_DrawGlypRun(i, pCharPos, pFont, pCache, nullptr, pObject2Device, | 825 pObject2Device, font_size, color); |
| 837 font_size, color, alpha_flag, pIccTransform); | |
| 838 if (!ret) { | 826 if (!ret) { |
| 839 RestoreState(false); | 827 RestoreState(false); |
| 840 return ret; | 828 return ret; |
| 841 } | 829 } |
| 842 } | 830 } |
| 843 const FXTEXT_CHARPOS* char_pos = pCharPos + i; | 831 const FXTEXT_CHARPOS* char_pos = pCharPos + i; |
| 844 CFX_Matrix glphy_matrix; | 832 CFX_Matrix glphy_matrix; |
| 845 if (font_size < 0) { | 833 if (font_size < 0) { |
| 846 glphy_matrix.Concat(-1, 0, 0, -1, 0, 0); | 834 glphy_matrix.Concat(-1, 0, 0, -1, 0, 0); |
| 847 } | 835 } |
| 848 if (char_pos->m_bGlyphAdjust) { | 836 if (char_pos->m_bGlyphAdjust) { |
| 849 glphy_matrix.Concat( | 837 glphy_matrix.Concat( |
| 850 char_pos->m_AdjustMatrix[0], char_pos->m_AdjustMatrix[1], | 838 char_pos->m_AdjustMatrix[0], char_pos->m_AdjustMatrix[1], |
| 851 char_pos->m_AdjustMatrix[2], char_pos->m_AdjustMatrix[3], 0, 0); | 839 char_pos->m_AdjustMatrix[2], char_pos->m_AdjustMatrix[3], 0, 0); |
| 852 } | 840 } |
| 853 ret = CG_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix, | 841 ret = CG_DrawGlyphRun(1, char_pos, pFont, pCache, &glphy_matrix, |
| 854 pObject2Device, font_size, color, alpha_flag, | 842 pObject2Device, font_size, color); |
| 855 pIccTransform); | |
| 856 if (!ret) { | 843 if (!ret) { |
| 857 RestoreState(false); | 844 RestoreState(false); |
| 858 return ret; | 845 return ret; |
| 859 } | 846 } |
| 860 i++; | 847 i++; |
| 861 pCharPos += i; | 848 pCharPos += i; |
| 862 nChars -= i; | 849 nChars -= i; |
| 863 i = 0; | 850 i = 0; |
| 864 } else { | 851 } else { |
| 865 i++; | 852 i++; |
| 866 } | 853 } |
| 867 } | 854 } |
| 868 if (i > 0) { | 855 if (i > 0) { |
| 869 ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, nullptr, pObject2Device, | 856 ret = CG_DrawGlyphRun(i, pCharPos, pFont, pCache, nullptr, pObject2Device, |
| 870 font_size, color, alpha_flag, pIccTransform); | 857 font_size, color); |
| 871 } | 858 } |
| 872 RestoreState(false); | 859 RestoreState(false); |
| 873 return ret; | 860 return ret; |
| 874 } | 861 } |
| 862 |
| 875 void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, | 863 void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, |
| 876 FX_ARGB argb, | 864 FX_ARGB argb, |
| 877 FX_FLOAT lineWidth) { | 865 FX_FLOAT lineWidth) { |
| 878 if (!graphState) | 866 if (!graphState) |
| 879 return; | 867 return; |
| 880 | 868 |
| 881 CGContextSetLineWidth(m_context, lineWidth); | 869 CGContextSetLineWidth(m_context, lineWidth); |
| 882 CGLineCap cap; | 870 CGLineCap cap; |
| 883 switch (graphState->m_LineCap) { | 871 switch (graphState->m_LineCap) { |
| 884 case CFX_GraphStateData::LineCapRound: { | 872 case CFX_GraphStateData::LineCapRound: { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 points[i + 1].m_PointY, points[i + 2].m_PointX, | 940 points[i + 1].m_PointY, points[i + 2].m_PointX, |
| 953 points[i + 2].m_PointY); | 941 points[i + 2].m_PointY); |
| 954 i += 2; | 942 i += 2; |
| 955 } | 943 } |
| 956 } | 944 } |
| 957 if (points[i].m_Flag & FXPT_CLOSEFIGURE) { | 945 if (points[i].m_Flag & FXPT_CLOSEFIGURE) { |
| 958 CGContextClosePath(m_context); | 946 CGContextClosePath(m_context); |
| 959 } | 947 } |
| 960 } | 948 } |
| 961 } | 949 } |
| 950 |
| 962 void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, | 951 void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, |
| 963 int dest_top, | 952 int dest_top, |
| 964 int dest_width, | 953 int dest_width, |
| 965 int dest_height, | 954 int dest_height, |
| 966 CGRect* rect) { | 955 CGRect* rect) { |
| 967 int flip_y = m_foxitDevice2User.d * dest_height < 0 ? 1 : -1; | 956 int flip_y = m_foxitDevice2User.d * dest_height < 0 ? 1 : -1; |
| 968 int flip_x = m_foxitDevice2User.a * dest_width > 0 ? 1 : -1; | 957 int flip_x = m_foxitDevice2User.a * dest_width > 0 ? 1 : -1; |
| 969 if (flip_y < 0 || flip_x < 0) { | 958 if (flip_y >= 0 && flip_x >= 0) |
| 970 if (dest_height < 0) { | 959 return; |
| 971 dest_height = -dest_height; | 960 |
| 972 dest_top -= dest_height; | 961 if (dest_height < 0) { |
| 973 } | 962 dest_height = -dest_height; |
| 974 CGRect rt = CGRectApplyAffineTransform( | 963 dest_top -= dest_height; |
| 975 CGRectMake(dest_left, dest_top, dest_width, dest_height), | |
| 976 m_foxitDevice2User); | |
| 977 CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f, | |
| 978 offset_y = (rt.origin.y) + rt.size.height / 2.f; | |
| 979 CGAffineTransform transform = CGAffineTransformIdentity; | |
| 980 transform = CGAffineTransformConcat( | |
| 981 transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y)); | |
| 982 transform = CGAffineTransformConcat( | |
| 983 transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0)); | |
| 984 transform = CGAffineTransformConcat( | |
| 985 transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y)); | |
| 986 CGContextConcatCTM(m_context, transform); | |
| 987 if (rect) { | |
| 988 *rect = CGRectApplyAffineTransform(*rect, transform); | |
| 989 } | |
| 990 } | 964 } |
| 965 CGRect rt = CGRectApplyAffineTransform( |
| 966 CGRectMake(dest_left, dest_top, dest_width, dest_height), |
| 967 m_foxitDevice2User); |
| 968 CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f, |
| 969 offset_y = (rt.origin.y) + rt.size.height / 2.f; |
| 970 CGAffineTransform transform = CGAffineTransformIdentity; |
| 971 transform = CGAffineTransformConcat( |
| 972 transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y)); |
| 973 transform = CGAffineTransformConcat( |
| 974 transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0)); |
| 975 transform = CGAffineTransformConcat( |
| 976 transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y)); |
| 977 CGContextConcatCTM(m_context, transform); |
| 978 if (rect) |
| 979 *rect = CGRectApplyAffineTransform(*rect, transform); |
| 991 } | 980 } |
| 981 |
| 992 void CFX_QuartzDeviceDriver::ClearDriver() { | 982 void CFX_QuartzDeviceDriver::ClearDriver() { |
| 993 if (!m_context) | 983 if (!m_context) |
| 994 return; | 984 return; |
| 995 | 985 |
| 996 for (int i = 0; i < m_saveCount; ++i) { | 986 for (int i = 0; i < m_saveCount; ++i) { |
| 997 CGContextRestoreGState(m_context); | 987 CGContextRestoreGState(m_context); |
| 998 } | 988 } |
| 999 m_saveCount = 0; | 989 m_saveCount = 0; |
| 1000 if (m_context) { | 990 if (m_context) { |
| 1001 CGContextRelease(m_context); | 991 CGContextRelease(m_context); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 } | 1036 } |
| 1047 CFX_DIBitmap* pBitmap = new CFX_DIBitmap; | 1037 CFX_DIBitmap* pBitmap = new CFX_DIBitmap; |
| 1048 if (!pBitmap->Create(width, height, format)) { | 1038 if (!pBitmap->Create(width, height, format)) { |
| 1049 delete pBitmap; | 1039 delete pBitmap; |
| 1050 return FALSE; | 1040 return FALSE; |
| 1051 } | 1041 } |
| 1052 m_bOwnedBitmap = TRUE; | 1042 m_bOwnedBitmap = TRUE; |
| 1053 return Attach(pBitmap); | 1043 return Attach(pBitmap); |
| 1054 } | 1044 } |
| 1055 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 1045 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| OLD | NEW |