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 |