Chromium Code Reviews| 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/fxge/dib/dib_int.h" | 7 #include "core/fxge/dib/dib_int.h" |
| 8 | 8 |
| 9 #include "core/fxge/include/fx_dib.h" | 9 #include "core/fxge/include/fx_dib.h" |
| 10 | 10 |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 uint32_t flags, | 302 uint32_t flags, |
| 303 const FX_RECT* pDestClip) const { | 303 const FX_RECT* pDestClip) const { |
| 304 CFX_ImageTransformer transformer; | 304 CFX_ImageTransformer transformer; |
| 305 transformer.Start(this, pDestMatrix, flags, pDestClip); | 305 transformer.Start(this, pDestMatrix, flags, pDestClip); |
| 306 transformer.Continue(NULL); | 306 transformer.Continue(NULL); |
| 307 result_left = transformer.m_ResultLeft; | 307 result_left = transformer.m_ResultLeft; |
| 308 result_top = transformer.m_ResultTop; | 308 result_top = transformer.m_ResultTop; |
| 309 CFX_DIBitmap* pTransformed = transformer.m_Storer.Detach(); | 309 CFX_DIBitmap* pTransformed = transformer.m_Storer.Detach(); |
| 310 return pTransformed; | 310 return pTransformed; |
| 311 } | 311 } |
| 312 | |
| 312 CFX_DIBitmap* CFX_DIBSource::StretchTo(int dest_width, | 313 CFX_DIBitmap* CFX_DIBSource::StretchTo(int dest_width, |
| 313 int dest_height, | 314 int dest_height, |
| 314 uint32_t flags, | 315 uint32_t flags, |
| 315 const FX_RECT* pClip) const { | 316 const FX_RECT* pClip) const { |
| 316 FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height)); | 317 FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height)); |
| 317 if (pClip) { | 318 if (pClip) |
| 318 clip_rect.Intersect(*pClip); | 319 clip_rect.Intersect(*pClip); |
| 319 } | 320 |
| 320 if (clip_rect.IsEmpty()) { | 321 if (clip_rect.IsEmpty()) |
| 321 return NULL; | 322 return nullptr; |
| 322 } | 323 |
| 323 if (dest_width == m_Width && dest_height == m_Height) { | 324 if (dest_width == m_Width && dest_height == m_Height) |
| 324 return Clone(&clip_rect); | 325 return Clone(&clip_rect); |
| 325 } | 326 |
| 326 CFX_ImageStretcher stretcher; | |
| 327 CFX_BitmapStorer storer; | 327 CFX_BitmapStorer storer; |
| 328 if (stretcher.Start(&storer, this, dest_width, dest_height, clip_rect, | 328 CFX_ImageStretcher stretcher(&storer, this, dest_width, dest_height, |
| 329 flags)) { | 329 clip_rect, flags); |
| 330 stretcher.Continue(NULL); | 330 if (stretcher.Start()) |
| 331 } | 331 stretcher.Continue(nullptr); |
|
Tom Sepez
2016/05/12 00:03:08
Do we ever call this with non-nullptr?
Lei Zhang
2016/05/12 01:17:13
Yes, we pass a pPause variable in sometimes. Wheth
| |
| 332 return storer.Detach(); | 332 return storer.Detach(); |
| 333 } | 333 } |
| 334 | |
| 334 CFX_ImageTransformer::CFX_ImageTransformer() { | 335 CFX_ImageTransformer::CFX_ImageTransformer() { |
| 335 m_Status = 0; | 336 m_Status = 0; |
| 336 m_pMatrix = NULL; | 337 m_pMatrix = NULL; |
| 337 } | 338 } |
| 339 | |
| 338 CFX_ImageTransformer::~CFX_ImageTransformer() {} | 340 CFX_ImageTransformer::~CFX_ImageTransformer() {} |
| 341 | |
| 339 FX_BOOL CFX_ImageTransformer::Start(const CFX_DIBSource* pSrc, | 342 FX_BOOL CFX_ImageTransformer::Start(const CFX_DIBSource* pSrc, |
| 340 const CFX_Matrix* pDestMatrix, | 343 const CFX_Matrix* pDestMatrix, |
| 341 int flags, | 344 int flags, |
| 342 const FX_RECT* pDestClip) { | 345 const FX_RECT* pDestClip) { |
| 343 m_pMatrix = (CFX_Matrix*)pDestMatrix; | 346 m_pMatrix = (CFX_Matrix*)pDestMatrix; |
| 344 CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect(); | 347 CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect(); |
| 345 FX_RECT result_rect = unit_rect.GetClosestRect(); | 348 FX_RECT result_rect = unit_rect.GetClosestRect(); |
| 346 FX_RECT result_clip = result_rect; | 349 FX_RECT result_clip = result_rect; |
| 347 if (pDestClip) { | 350 if (pDestClip) |
| 348 result_clip.Intersect(*pDestClip); | 351 result_clip.Intersect(*pDestClip); |
| 349 } | 352 |
| 350 if (result_clip.IsEmpty()) { | 353 if (result_clip.IsEmpty()) |
| 351 return FALSE; | 354 return FALSE; |
| 352 } | 355 |
| 353 m_ResultLeft = result_clip.left; | 356 m_ResultLeft = result_clip.left; |
| 354 m_ResultTop = result_clip.top; | 357 m_ResultTop = result_clip.top; |
| 355 m_ResultWidth = result_clip.Width(); | 358 m_ResultWidth = result_clip.Width(); |
| 356 m_ResultHeight = result_clip.Height(); | 359 m_ResultHeight = result_clip.Height(); |
| 357 m_Flags = flags; | 360 m_Flags = flags; |
| 358 if (FXSYS_fabs(pDestMatrix->a) < FXSYS_fabs(pDestMatrix->b) / 20 && | 361 if (FXSYS_fabs(pDestMatrix->a) < FXSYS_fabs(pDestMatrix->b) / 20 && |
| 359 FXSYS_fabs(pDestMatrix->d) < FXSYS_fabs(pDestMatrix->c) / 20 && | 362 FXSYS_fabs(pDestMatrix->d) < FXSYS_fabs(pDestMatrix->c) / 20 && |
| 360 FXSYS_fabs(pDestMatrix->a) < 0.5f && FXSYS_fabs(pDestMatrix->d) < 0.5f) { | 363 FXSYS_fabs(pDestMatrix->a) < 0.5f && FXSYS_fabs(pDestMatrix->d) < 0.5f) { |
| 361 int dest_width = result_rect.Width(); | 364 int dest_width = result_rect.Width(); |
| 362 int dest_height = result_rect.Height(); | 365 int dest_height = result_rect.Height(); |
| 363 result_clip.Offset(-result_rect.left, -result_rect.top); | 366 result_clip.Offset(-result_rect.left, -result_rect.top); |
| 364 result_clip = FXDIB_SwapClipBox(result_clip, dest_width, dest_height, | 367 result_clip = FXDIB_SwapClipBox(result_clip, dest_width, dest_height, |
| 365 pDestMatrix->c > 0, pDestMatrix->b < 0); | 368 pDestMatrix->c > 0, pDestMatrix->b < 0); |
| 366 m_Stretcher.Start(&m_Storer, pSrc, dest_height, dest_width, result_clip, | 369 m_Stretcher.reset(new CFX_ImageStretcher(&m_Storer, pSrc, dest_height, |
| 367 flags); | 370 dest_width, result_clip, flags)); |
| 371 m_Stretcher->Start(); | |
| 368 m_Status = 1; | 372 m_Status = 1; |
| 369 return TRUE; | 373 return TRUE; |
| 370 } | 374 } |
| 371 if (FXSYS_fabs(pDestMatrix->b) < FIX16_005 && | 375 if (FXSYS_fabs(pDestMatrix->b) < FIX16_005 && |
| 372 FXSYS_fabs(pDestMatrix->c) < FIX16_005) { | 376 FXSYS_fabs(pDestMatrix->c) < FIX16_005) { |
| 373 int dest_width = pDestMatrix->a > 0 ? (int)FXSYS_ceil(pDestMatrix->a) | 377 int dest_width = pDestMatrix->a > 0 ? (int)FXSYS_ceil(pDestMatrix->a) |
| 374 : (int)FXSYS_floor(pDestMatrix->a); | 378 : (int)FXSYS_floor(pDestMatrix->a); |
| 375 int dest_height = pDestMatrix->d > 0 ? (int)-FXSYS_ceil(pDestMatrix->d) | 379 int dest_height = pDestMatrix->d > 0 ? (int)-FXSYS_ceil(pDestMatrix->d) |
| 376 : (int)-FXSYS_floor(pDestMatrix->d); | 380 : (int)-FXSYS_floor(pDestMatrix->d); |
| 377 result_clip.Offset(-result_rect.left, -result_rect.top); | 381 result_clip.Offset(-result_rect.left, -result_rect.top); |
| 378 m_Stretcher.Start(&m_Storer, pSrc, dest_width, dest_height, result_clip, | 382 m_Stretcher.reset(new CFX_ImageStretcher(&m_Storer, pSrc, dest_width, |
| 379 flags); | 383 dest_height, result_clip, flags)); |
| 384 m_Stretcher->Start(); | |
| 380 m_Status = 2; | 385 m_Status = 2; |
| 381 return TRUE; | 386 return TRUE; |
| 382 } | 387 } |
| 383 int stretch_width = | 388 int stretch_width = |
| 384 (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->a, pDestMatrix->b)); | 389 (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->a, pDestMatrix->b)); |
| 385 int stretch_height = | 390 int stretch_height = |
| 386 (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->c, pDestMatrix->d)); | 391 (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->c, pDestMatrix->d)); |
| 387 CFX_Matrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, | 392 CFX_Matrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, |
| 388 (FX_FLOAT)(stretch_height)); | 393 (FX_FLOAT)(stretch_height)); |
| 389 stretch2dest.Concat( | 394 stretch2dest.Concat( |
| 390 pDestMatrix->a / stretch_width, pDestMatrix->b / stretch_width, | 395 pDestMatrix->a / stretch_width, pDestMatrix->b / stretch_width, |
| 391 pDestMatrix->c / stretch_height, pDestMatrix->d / stretch_height, | 396 pDestMatrix->c / stretch_height, pDestMatrix->d / stretch_height, |
| 392 pDestMatrix->e, pDestMatrix->f); | 397 pDestMatrix->e, pDestMatrix->f); |
| 393 m_dest2stretch.SetReverse(stretch2dest); | 398 m_dest2stretch.SetReverse(stretch2dest); |
| 394 CFX_FloatRect clip_rect_f(result_clip); | 399 CFX_FloatRect clip_rect_f(result_clip); |
| 395 clip_rect_f.Transform(&m_dest2stretch); | 400 clip_rect_f.Transform(&m_dest2stretch); |
| 396 m_StretchClip = clip_rect_f.GetOutterRect(); | 401 m_StretchClip = clip_rect_f.GetOutterRect(); |
| 397 m_StretchClip.Intersect(0, 0, stretch_width, stretch_height); | 402 m_StretchClip.Intersect(0, 0, stretch_width, stretch_height); |
| 398 m_Stretcher.Start(&m_Storer, pSrc, stretch_width, stretch_height, | 403 m_Stretcher.reset(new CFX_ImageStretcher( |
| 399 m_StretchClip, flags); | 404 &m_Storer, pSrc, stretch_width, stretch_height, m_StretchClip, flags)); |
| 405 m_Stretcher->Start(); | |
| 400 m_Status = 3; | 406 m_Status = 3; |
| 401 return TRUE; | 407 return TRUE; |
| 402 } | 408 } |
| 403 | 409 |
| 404 FX_BOOL CFX_ImageTransformer::Continue(IFX_Pause* pPause) { | 410 FX_BOOL CFX_ImageTransformer::Continue(IFX_Pause* pPause) { |
| 405 if (m_Status == 1) { | 411 if (m_Status == 1) { |
| 406 if (m_Stretcher.Continue(pPause)) { | 412 if (m_Stretcher->Continue(pPause)) |
| 407 return TRUE; | 413 return TRUE; |
| 408 } | 414 |
| 409 if (m_Storer.GetBitmap()) { | 415 if (m_Storer.GetBitmap()) { |
| 410 m_Storer.Replace( | 416 m_Storer.Replace( |
| 411 m_Storer.GetBitmap()->SwapXY(m_pMatrix->c > 0, m_pMatrix->b < 0)); | 417 m_Storer.GetBitmap()->SwapXY(m_pMatrix->c > 0, m_pMatrix->b < 0)); |
| 412 } | 418 } |
| 413 return FALSE; | 419 return FALSE; |
| 414 } | 420 } |
| 415 if (m_Status == 2) { | 421 |
| 416 return m_Stretcher.Continue(pPause); | 422 if (m_Status == 2) |
| 417 } | 423 return m_Stretcher->Continue(pPause); |
| 418 if (m_Status != 3) { | 424 |
| 425 if (m_Status != 3) | |
| 419 return FALSE; | 426 return FALSE; |
| 420 } | 427 |
| 421 if (m_Stretcher.Continue(pPause)) { | 428 if (m_Stretcher->Continue(pPause)) |
| 422 return TRUE; | 429 return TRUE; |
| 423 } | 430 |
| 424 int stretch_width = m_StretchClip.Width(); | 431 int stretch_width = m_StretchClip.Width(); |
| 425 int stretch_height = m_StretchClip.Height(); | 432 int stretch_height = m_StretchClip.Height(); |
| 426 if (!m_Storer.GetBitmap()) { | 433 if (!m_Storer.GetBitmap()) |
| 427 return FALSE; | 434 return FALSE; |
| 428 } | 435 |
| 429 const uint8_t* stretch_buf = m_Storer.GetBitmap()->GetBuffer(); | 436 const uint8_t* stretch_buf = m_Storer.GetBitmap()->GetBuffer(); |
| 430 const uint8_t* stretch_buf_mask = NULL; | 437 const uint8_t* stretch_buf_mask = nullptr; |
| 431 if (m_Storer.GetBitmap()->m_pAlphaMask) { | 438 if (m_Storer.GetBitmap()->m_pAlphaMask) |
| 432 stretch_buf_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetBuffer(); | 439 stretch_buf_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetBuffer(); |
| 433 } | 440 |
| 434 int stretch_pitch = m_Storer.GetBitmap()->GetPitch(); | 441 int stretch_pitch = m_Storer.GetBitmap()->GetPitch(); |
| 435 CFX_DIBitmap* pTransformed = new CFX_DIBitmap; | 442 std::unique_ptr<CFX_DIBitmap> pTransformed(new CFX_DIBitmap); |
| 436 FXDIB_Format transformF = GetTransformedFormat(m_Stretcher.m_pSource); | 443 FXDIB_Format transformF = GetTransformedFormat(m_Stretcher->source()); |
| 437 if (!pTransformed->Create(m_ResultWidth, m_ResultHeight, transformF)) { | 444 if (!pTransformed->Create(m_ResultWidth, m_ResultHeight, transformF)) |
| 438 delete pTransformed; | |
| 439 return FALSE; | 445 return FALSE; |
| 440 } | 446 |
| 441 pTransformed->Clear(0); | 447 pTransformed->Clear(0); |
| 442 if (pTransformed->m_pAlphaMask) { | 448 if (pTransformed->m_pAlphaMask) |
| 443 pTransformed->m_pAlphaMask->Clear(0); | 449 pTransformed->m_pAlphaMask->Clear(0); |
| 444 } | 450 |
| 445 CFX_Matrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, (FX_FLOAT)(m_ResultLeft), | 451 CFX_Matrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, (FX_FLOAT)(m_ResultLeft), |
| 446 (FX_FLOAT)(m_ResultTop)); | 452 (FX_FLOAT)(m_ResultTop)); |
| 447 result2stretch.Concat(m_dest2stretch); | 453 result2stretch.Concat(m_dest2stretch); |
| 448 result2stretch.TranslateI(-m_StretchClip.left, -m_StretchClip.top); | 454 result2stretch.TranslateI(-m_StretchClip.left, -m_StretchClip.top); |
| 449 if (!stretch_buf_mask && pTransformed->m_pAlphaMask) { | 455 if (!stretch_buf_mask && pTransformed->m_pAlphaMask) { |
| 450 pTransformed->m_pAlphaMask->Clear(0xff000000); | 456 pTransformed->m_pAlphaMask->Clear(0xff000000); |
| 451 } else if (pTransformed->m_pAlphaMask) { | 457 } else if (pTransformed->m_pAlphaMask) { |
| 452 int stretch_pitch_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetPitch(); | 458 int stretch_pitch_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetPitch(); |
| 453 if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { | 459 if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { |
| 454 CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); | 460 CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 936 FXARGB_MAKE(0xff, src_pos[2], src_pos[1], src_pos[0])); | 942 FXARGB_MAKE(0xff, src_pos[2], src_pos[1], src_pos[0])); |
| 937 } | 943 } |
| 938 } | 944 } |
| 939 } | 945 } |
| 940 dest_pos += destBpp; | 946 dest_pos += destBpp; |
| 941 } | 947 } |
| 942 } | 948 } |
| 943 } | 949 } |
| 944 } | 950 } |
| 945 } | 951 } |
| 946 m_Storer.Replace(pTransformed); | 952 m_Storer.Replace(pTransformed.release()); |
| 947 return FALSE; | 953 return FALSE; |
| 948 } | 954 } |
| OLD | NEW |