1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "core/include/fxge/fx_ge.h" 6 7 //#define _SKIA_SUPPORT_ 8 #if defined(_SKIA_SUPPORT_) 9 #include "SkBlitter.h" 10 #include "core/include/fxcodec/fx_codec.h" 11 #include "fx_skia_blitter_new.h" 12 13 // We use our own renderer here to make it simple 14 void CFX_SkiaRenderer::blitAntiH(int x, 15 int y, 16 const SkAlpha antialias[], 17 const int16_t runs[]) { 18 FXSYS_assert(m_Alpha); 19 if (!m_pOriDevice && !composite_span) 20 return; 21 if (y < m_ClipBox.top || y >= m_ClipBox.bottom) 22 return; 23 while (1) { 24 int width = runs[0]; 25 SkASSERT(width >= 0); 26 if (width <= 0) 27 return; 28 unsigned aa = antialias[0]; 29 if (aa) 30 (*composite_span)(m_pDestScan, m_pOriScan, 0, x, width, y, aa, 31 m_ClipBox.top, m_ClipBox.left, m_ClipBox.right, 32 m_pClipScan, m_pDestExtraAlphaScan); 33 runs += width; 34 antialias += width; 35 x += width; 36 } 37 } 38 39 void CFX_SkiaRenderer::blitH(int x, int y, int width) { 40 FXSYS_assert(m_Alpha && width); 41 if (y < m_ClipBox.top || y >= m_ClipBox.bottom) 42 return; 43 (*composite_span)(m_pDestScan, m_pOriScan, 0, x, width, y, 255, m_ClipBox.top, 44 m_ClipBox.left, m_ClipBox.right, m_pClipScan, 45 m_pDestExtraAlphaScan); 46 } 47 48 void CFX_SkiaRenderer::blitV(int x, int y, int height, SkAlpha alpha) { 49 FXSYS_assert(m_Alpha && alpha); 50 if (alpha == 255) { 51 blitRect(x, y, 1, height); 52 } else { 53 int16_t runs[2]; 54 runs[0] = 1; 55 runs[1] = 0; 56 while (--height >= 0) { 57 if (y >= m_ClipBox.bottom) 58 return; 59 blitAntiH(x, y++, &alpha, runs); 60 } 61 } 62 } 63 void CFX_SkiaRenderer::blitRect(int x, int y, int width, int height) { 64 FXSYS_assert(m_Alpha && width); 65 while (--height >= 0) { 66 if (y >= m_ClipBox.bottom) 67 return; 68 blitH(x, y++, width); 69 } 70 } 71 72 void CFX_SkiaRenderer::blitAntiRect(int x, 73 int y, 74 int width, 75 int height, 76 SkAlpha leftAlpha, 77 SkAlpha rightAlpha) { 78 blitV(x++, y, height, leftAlpha); 79 if (width > 0) { 80 blitRect(x, y, width, height); 81 x += width; 82 } 83 blitV(x, y, height, rightAlpha); 84 } 85 /*---------------------------------------------------------------------------------------------------*/ 86 void CFX_SkiaRenderer::CompositeSpan1bpp_0(uint8_t* dest_scan, 87 uint8_t* ori_scan, 88 int Bpp, 89 int span_left, 90 int span_len, 91 int span_top, 92 uint8_t cover_scan, 93 int clip_top, 94 int clip_left, 95 int clip_right, 96 uint8_t* clip_scan, 97 uint8_t* dest_extra_alpha_scan) { 98 ASSERT(!m_bRgbByteOrder); 99 ASSERT(!m_pDevice->IsCmykImage()); 100 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left / 8; 101 int col_start = span_left < clip_left ? clip_left - span_left : 0; 102 int col_end = 103 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 104 if (col_end < col_start) 105 return; // do nothing. 106 dest_scan += col_start / 8; 107 108 int index = 0; 109 if (m_pDevice->GetPalette()) { 110 for (int i = 0; i < 2; i++) { 111 if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) 112 index = i; 113 } 114 } else { 115 index = ((uint8_t)m_Color == 0xff) ? 1 : 0; 116 } 117 uint8_t* dest_scan1 = dest_scan; 118 int src_alpha = m_Alpha * cover_scan / 255; 119 for (int col = col_start; col < col_end; col++) { 120 if (src_alpha) { 121 if (!index) 122 *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); 123 else 124 *dest_scan1 |= 1 << (7 - (col + span_left) % 8); 125 } 126 dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; 127 } 128 } 129 void CFX_SkiaRenderer::CompositeSpan1bpp_4(uint8_t* dest_scan, 130 uint8_t* ori_scan, 131 int Bpp, 132 int span_left, 133 int span_len, 134 int span_top, 135 uint8_t cover_scan, 136 int clip_top, 137 int clip_left, 138 int clip_right, 139 uint8_t* clip_scan, 140 uint8_t* dest_extra_alpha_scan) { 141 ASSERT(!m_bRgbByteOrder); 142 ASSERT(!m_pDevice->IsCmykImage()); 143 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left / 8; 144 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 145 clip_left + span_left; 146 int col_start = span_left < clip_left ? clip_left - span_left : 0; 147 int col_end = 148 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 149 if (col_end < col_start) 150 return; // do nothing. 151 dest_scan += col_start / 8; 152 153 int index = 0; 154 if (m_pDevice->GetPalette()) { 155 for (int i = 0; i < 2; i++) { 156 if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) 157 index = i; 158 } 159 } else { 160 index = ((uint8_t)m_Color == 0xff) ? 1 : 0; 161 } 162 uint8_t* dest_scan1 = dest_scan; 163 int src_alpha = m_Alpha * cover_scan / 255; 164 for (int col = col_start; col < col_end; col++) { 165 int src_alpha1 = src_alpha * clip_scan[col] / 255; 166 if (src_alpha1) { 167 if (!index) 168 *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); 169 else 170 *dest_scan1 |= 1 << (7 - (col + span_left) % 8); 171 } 172 dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; 173 } 174 } 175 /*-----------------------------------------------------------------------------------------------------*/ 176 void CFX_SkiaRenderer::CompositeSpanGray_2(uint8_t* dest_scan, 177 uint8_t* ori_scan, 178 int Bpp, 179 int span_left, 180 int span_len, 181 int span_top, 182 uint8_t cover_scan, 183 int clip_top, 184 int clip_left, 185 int clip_right, 186 uint8_t* clip_scan, 187 uint8_t* dest_extra_alpha_scan) { 188 ASSERT(!m_pDevice->IsCmykImage()); 189 ASSERT(!m_bRgbByteOrder); 190 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; 191 int col_start = span_left < clip_left ? clip_left - span_left : 0; 192 int col_end = 193 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 194 if (col_end < col_start) 195 return; // do nothing. 196 dest_scan += col_start; 197 if (cover_scan == 255 && m_Alpha == 255) { 198 FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), 199 col_end - col_start); 200 return; 201 } 202 int src_alpha = m_Alpha * cover_scan / 255; 203 for (int col = col_start; col < col_end; col++) { 204 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); 205 dest_scan++; 206 } 207 } 208 void CFX_SkiaRenderer::CompositeSpanGray_3(uint8_t* dest_scan, 209 uint8_t* ori_scan, 210 int Bpp, 211 int span_left, 212 int span_len, 213 int span_top, 214 uint8_t cover_scan, 215 int clip_top, 216 int clip_left, 217 int clip_right, 218 uint8_t* clip_scan, 219 uint8_t* dest_extra_alpha_scan) { 220 ASSERT(!m_pDevice->IsCmykImage()); 221 ASSERT(!m_bRgbByteOrder); 222 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; 223 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left; 224 int col_start = span_left < clip_left ? clip_left - span_left : 0; 225 int col_end = 226 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 227 if (col_end < col_start) 228 return; // do nothing. 229 dest_scan += col_start; 230 ori_scan += col_start; 231 if (m_Alpha == 255 && cover_scan == 255) { 232 FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), 233 col_end - col_start); 234 } else { 235 int src_alpha = m_Alpha; 236 #if 1 237 for (int col = col_start; col < col_end; col++) { 238 int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); 239 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); 240 dest_scan++; 241 } 242 #else 243 if (m_bFullCover) { 244 if (src_alpha == 255) { 245 FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), 246 col_end - col_start); 247 return; 248 } 249 for (int col = col_start; col < col_end; col++) 250 *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); 251 } else { 252 for (int col = col_start; col < col_end; col++) { 253 int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); 254 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); 255 dest_scan++; 256 } 257 } 258 #endif 259 } 260 } 261 262 void CFX_SkiaRenderer::CompositeSpanGray_6(uint8_t* dest_scan, 263 uint8_t* ori_scan, 264 int Bpp, 265 int span_left, 266 int span_len, 267 int span_top, 268 uint8_t cover_scan, 269 int clip_top, 270 int clip_left, 271 int clip_right, 272 uint8_t* clip_scan, 273 uint8_t* dest_extra_alpha_scan) { 274 ASSERT(!m_bRgbByteOrder); 275 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; 276 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 277 clip_left + span_left; 278 int col_start = span_left < clip_left ? clip_left - span_left : 0; 279 int col_end = 280 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 281 if (col_end < col_start) 282 return; // do nothing. 283 dest_scan += col_start; 284 int src_alpha = m_Alpha * cover_scan / 255; 285 for (int col = col_start; col < col_end; col++) { 286 int src_alpha1 = src_alpha * clip_scan[col] / 255; 287 if (!src_alpha1) { 288 dest_scan++; 289 continue; 290 } 291 if (src_alpha1 == 255) 292 *dest_scan++ = m_Gray; 293 else { 294 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha1); 295 dest_scan++; 296 } 297 } 298 } 299 300 void CFX_SkiaRenderer::CompositeSpanGray_7(uint8_t* dest_scan, 301 uint8_t* ori_scan, 302 int Bpp, 303 int span_left, 304 int span_len, 305 int span_top, 306 uint8_t cover_scan, 307 int clip_top, 308 int clip_left, 309 int clip_right, 310 uint8_t* clip_scan, 311 uint8_t* dest_extra_alpha_scan) { 312 ASSERT(!m_pDevice->IsCmykImage()); 313 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; 314 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left; 315 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 316 clip_left + span_left; 317 int col_start = span_left < clip_left ? clip_left - span_left : 0; 318 int col_end = 319 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 320 if (col_end < col_start) 321 return; // do nothing. 322 dest_scan += col_start; 323 ori_scan += col_start; 324 #if 1 325 for (int col = col_start; col < col_end; col++) { 326 int src_alpha = m_Alpha * clip_scan[col] / 255; 327 if (src_alpha == 255 && cover_scan == 255) { 328 *dest_scan++ = m_Gray; 329 ori_scan++; 330 continue; 331 } 332 int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); 333 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); 334 dest_scan++; 335 } 336 337 #else 338 if (m_bFullCover) { 339 for (int col = col_start; col < col_end; col++) { 340 int src_alpha = m_Alpha * clip_scan[col] / 255; 341 if (!src_alpha) { 342 dest_scan++; 343 ori_scan++; 344 continue; 345 } 346 if (src_alpha == 255) { 347 *dest_scan++ = m_Gray; 348 ori_scan++; 349 continue; 350 } 351 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); 352 } 353 } else { 354 for (int col = col_start; col < col_end; col++) { 355 int src_alpha = m_Alpha * clip_scan[col] / 255; 356 if (src_alpha == 255 && cover_scan == 255) { 357 *dest_scan++ = m_Gray; 358 ori_scan++; 359 continue; 360 } 361 int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); 362 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); 363 dest_scan++; 364 } 365 } 366 #endif 367 } 368 /*--------------------------------------------------------------------------------------------------*/ 369 370 void CFX_SkiaRenderer::CompositeSpanARGB_2(uint8_t* dest_scan, 371 uint8_t* ori_scan, 372 int Bpp, 373 int span_left, 374 int span_len, 375 int span_top, 376 uint8_t cover_scan, 377 int clip_top, 378 int clip_left, 379 int clip_right, 380 uint8_t* clip_scan, 381 uint8_t* dest_extra_alpha_scan) { 382 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); 383 int col_start = span_left < clip_left ? clip_left - span_left : 0; 384 int col_end = 385 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 386 if (col_end < col_start) 387 return; // do nothing. 388 dest_scan += col_start << 2; 389 if (m_Alpha == 255 && cover_scan == 255) { 390 FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); 391 return; 392 } 393 int src_alpha; 394 #if 0 395 if (m_bFullCover) { 396 if (m_Alpha == 255) { 397 FXSYS_memset(dest_scan, m_Color, (col_end - col_start)<<2); 398 return; 399 } 400 } 401 else 402 #endif 403 src_alpha = m_Alpha * cover_scan / 255; 404 for (int col = col_start; col < col_end; col++) { 405 // Dest format: Argb 406 // calculate destination alpha (it's union of source and dest alpha) 407 if (dest_scan[3] == 0) { 408 dest_scan[3] = src_alpha; 409 *dest_scan++ = m_Blue; 410 *dest_scan++ = m_Green; 411 *dest_scan = m_Red; 412 dest_scan += 2; 413 continue; 414 } 415 uint8_t dest_alpha = 416 dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; 417 dest_scan[3] = dest_alpha; 418 int alpha_ratio = src_alpha * 255 / dest_alpha; 419 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 420 dest_scan++; 421 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 422 dest_scan++; 423 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 424 dest_scan += 2; 425 } 426 } 427 428 void CFX_SkiaRenderer::CompositeSpanARGB_3(uint8_t* dest_scan, 429 uint8_t* ori_scan, 430 int Bpp, 431 int span_left, 432 int span_len, 433 int span_top, 434 uint8_t cover_scan, 435 int clip_top, 436 int clip_left, 437 int clip_right, 438 uint8_t* clip_scan, 439 uint8_t* dest_extra_alpha_scan) { 440 ASSERT(!m_pDevice->IsCmykImage()); 441 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); 442 // ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); 443 int col_start = span_left < clip_left ? clip_left - span_left : 0; 444 int col_end = 445 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 446 if (col_end < col_start) 447 return; // do nothing. 448 dest_scan += col_start << 2; 449 // ori_scan += col_start << 2; 450 451 if (m_Alpha == 255 && cover_scan == 255) { 452 FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); 453 return; 454 } 455 if (cover_scan == 255) { 456 int dst_color = (0x00ffffff & m_Color) | (m_Alpha << 24); 457 FXSYS_memset(dest_scan, dst_color, (col_end - col_start) << 2); 458 return; 459 } 460 // Do not need origin bitmap, because of merge in pure transparent background 461 int src_alpha_covered = m_Alpha * cover_scan / 255; 462 for (int col = col_start; col < col_end; col++) { 463 // shortcut 464 if (dest_scan[3] == 0) { 465 dest_scan[3] = src_alpha_covered; 466 *dest_scan++ = m_Blue; 467 *dest_scan++ = m_Green; 468 *dest_scan = m_Red; 469 dest_scan += 2; 470 continue; 471 } 472 // We should do alpha transition and color transition 473 // alpha fg color fg 474 // alpha bg color bg 475 // alpha cover color cover 476 dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], m_Alpha, cover_scan); 477 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover_scan); 478 dest_scan++; 479 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover_scan); 480 dest_scan++; 481 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover_scan); 482 dest_scan += 2; 483 } 484 } 485 void CFX_SkiaRenderer::CompositeSpanARGB_6(uint8_t* dest_scan, 486 uint8_t* ori_scan, 487 int Bpp, 488 int span_left, 489 int span_len, 490 int span_top, 491 uint8_t cover_scan, 492 int clip_top, 493 int clip_left, 494 int clip_right, 495 uint8_t* clip_scan, 496 uint8_t* dest_extra_alpha_scan) { 497 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); 498 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 499 clip_left + span_left; 500 int col_start = span_left < clip_left ? clip_left - span_left : 0; 501 int col_end = 502 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 503 if (col_end < col_start) 504 return; // do nothing. 505 dest_scan += col_start << 2; 506 #if 1 507 int src_alpha = m_Alpha * cover_scan / 255; 508 for (int col = col_start; col < col_end; col++) { 509 int src_alpha1 = src_alpha * clip_scan[col] / 255; 510 if (!src_alpha1) { 511 dest_scan += 4; 512 continue; 513 } 514 if (src_alpha1 == 255) { 515 *(FX_DWORD*)dest_scan = m_Color; 516 dest_scan += 4; 517 } else { 518 // Dest format: Argb 519 // calculate destination alpha (it's union of source and dest alpha) 520 if (dest_scan[3] == 0) { 521 dest_scan[3] = src_alpha1; 522 *dest_scan++ = m_Blue; 523 *dest_scan++ = m_Green; 524 *dest_scan = m_Red; 525 dest_scan += 2; 526 continue; 527 } 528 uint8_t dest_alpha = 529 dest_scan[3] + src_alpha1 - dest_scan[3] * src_alpha1 / 255; 530 dest_scan[3] = dest_alpha; 531 int alpha_ratio = src_alpha1 * 255 / dest_alpha; 532 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 533 dest_scan++; 534 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 535 dest_scan++; 536 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 537 dest_scan += 2; 538 } 539 } 540 #else 541 if (m_bFullCover) { 542 for (int col = col_start; col < col_end; col++) { 543 int src_alpha = m_Alpha * clip_scan[col] / 255; 544 if (!src_alpha) { 545 dest_scan += 4; 546 continue; 547 } 548 if (src_alpha == 255) { 549 *(FX_DWORD*)dest_scan = m_Color; 550 dest_scan += 4; 551 continue; 552 } else { 553 // Dest format: Argb 554 // calculate destination alpha (it's union of source and dest alpha) 555 if (dest_scan[3] == 0) { 556 dest_scan[3] = src_alpha; 557 *dest_scan++ = m_Blue; 558 *dest_scan++ = m_Green; 559 *dest_scan = m_Red; 560 dest_scan += 2; 561 continue; 562 } 563 uint8_t dest_alpha = 564 dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; 565 dest_scan[3] = dest_alpha; 566 int alpha_ratio = src_alpha * 255 / dest_alpha; 567 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 568 dest_scan++; 569 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 570 dest_scan++; 571 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 572 dest_scan += 2; 573 } 574 } 575 } else { 576 int src_alpha = m_Alpha * cover_scan / 255; 577 for (int col = col_start; col < col_end; col++) { 578 int src_alpha1 = src_alpha * clip_scan[col] / 255; 579 if (!src_alpha1) { 580 dest_scan += 4; 581 continue; 582 } 583 if (src_alpha1 == 255) { 584 *(FX_DWORD*)dest_scan = m_Color; 585 dest_scan += 4; 586 } else { 587 // Dest format: Argb 588 // calculate destination alpha (it's union of source and dest alpha) 589 if (dest_scan[3] == 0) { 590 dest_scan[3] = src_alpha1; 591 *dest_scan++ = m_Blue; 592 *dest_scan++ = m_Green; 593 *dest_scan = m_Red; 594 dest_scan += 2; 595 continue; 596 } 597 uint8_t dest_alpha = 598 dest_scan[3] + src_alpha1 - dest_scan[3] * src_alpha1 / 255; 599 dest_scan[3] = dest_alpha; 600 int alpha_ratio = src_alpha1 * 255 / dest_alpha; 601 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 602 dest_scan++; 603 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 604 dest_scan++; 605 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 606 dest_scan += 2; 607 } 608 } 609 } 610 #endif 611 } 612 613 void CFX_SkiaRenderer::CompositeSpanARGB_7(uint8_t* dest_scan, 614 uint8_t* ori_scan, 615 int Bpp, 616 int span_left, 617 int span_len, 618 int span_top, 619 uint8_t cover_scan, 620 int clip_top, 621 int clip_left, 622 int clip_right, 623 uint8_t* clip_scan, 624 uint8_t* dest_extra_alpha_scan) { 625 ASSERT(!m_pDevice->IsCmykImage()); 626 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); 627 // ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); 628 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 629 clip_left + span_left; 630 int col_start = span_left < clip_left ? clip_left - span_left : 0; 631 int col_end = 632 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 633 if (col_end < col_start) 634 return; // do nothing. 635 dest_scan += col_start << 2; 636 // ori_scan += col_start << 2; 637 // Do not need origin bitmap, because of merge in pure transparent background 638 for (int col = col_start; col < col_end; col++) { 639 int src_alpha = m_Alpha * clip_scan[col] / 255; 640 int src_alpha_covered = src_alpha * cover_scan / 255; 641 // shortcut 642 if (src_alpha_covered == 0) { 643 dest_scan += 4; 644 continue; 645 } 646 // shortcut 647 if (cover_scan == 255 || dest_scan[3] == 0) { 648 // origin alpha always zero, just get src alpha 649 dest_scan[3] = src_alpha_covered; 650 *dest_scan++ = m_Blue; 651 *dest_scan++ = m_Green; 652 *dest_scan = m_Red; 653 dest_scan += 2; 654 continue; 655 } 656 // We should do alpha transition and color transition 657 // alpha fg color fg 658 // alpha bg color bg 659 // alpha cover color cover 660 dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover_scan); 661 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover_scan); 662 dest_scan++; 663 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover_scan); 664 dest_scan++; 665 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover_scan); 666 dest_scan += 2; 667 } 668 } 669 670 /*-----------------------------------------------------------------------------------------------------------*/ 671 void CFX_SkiaRenderer::CompositeSpanRGB32_2(uint8_t* dest_scan, 672 uint8_t* ori_scan, 673 int Bpp, 674 int span_left, 675 int span_len, 676 int span_top, 677 uint8_t cover_scan, 678 int clip_top, 679 int clip_left, 680 int clip_right, 681 uint8_t* clip_scan, 682 uint8_t* dest_extra_alpha_scan) { 683 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); 684 int col_start = span_left < clip_left ? clip_left - span_left : 0; 685 int col_end = 686 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 687 if (col_end < col_start) 688 return; // do nothing. 689 dest_scan += (col_start << 2); 690 if (m_Alpha == 255 && cover_scan == 255) { 691 FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); 692 return; 693 } 694 int src_alpha; 695 #if 0 696 if (m_bFullCover) 697 src_alpha = m_Alpha; 698 else 699 #endif 700 src_alpha = m_Alpha * cover_scan / 255; 701 for (int col = col_start; col < col_end; col++) { 702 // Dest format: Rgb32 703 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); 704 dest_scan++; 705 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); 706 dest_scan++; 707 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); 708 dest_scan += 2; 709 } 710 } 711 void CFX_SkiaRenderer::CompositeSpanRGB32_3(uint8_t* dest_scan, 712 uint8_t* ori_scan, 713 int Bpp, 714 int span_left, 715 int span_len, 716 int span_top, 717 uint8_t cover_scan, 718 int clip_top, 719 int clip_left, 720 int clip_right, 721 uint8_t* clip_scan, 722 uint8_t* dest_extra_alpha_scan) { 723 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); 724 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left << 2); 725 int col_start = span_left < clip_left ? clip_left - span_left : 0; 726 int col_end = 727 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 728 if (col_end < col_start) 729 return; // do nothing. 730 dest_scan += col_start << 2; 731 ori_scan += col_start << 2; 732 if (m_Alpha == 255 && cover_scan == 255) { 733 FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); 734 return; 735 } 736 int src_alpha = m_Alpha; 737 for (int col = col_start; col < col_end; col++) { 738 #if 0 739 if (m_bFullCover) { 740 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); 741 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); 742 *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); 743 dest_scan += 2; ori_scan += 2; 744 continue; 745 } 746 #endif 747 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); 748 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); 749 int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); 750 ori_scan += 2; 751 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); 752 dest_scan++; 753 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); 754 dest_scan++; 755 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); 756 dest_scan += 2; 757 } 758 } 759 void CFX_SkiaRenderer::CompositeSpanRGB32_6(uint8_t* dest_scan, 760 uint8_t* ori_scan, 761 int Bpp, 762 int span_left, 763 int span_len, 764 int span_top, 765 uint8_t cover_scan, 766 int clip_top, 767 int clip_left, 768 int clip_right, 769 uint8_t* clip_scan, 770 uint8_t* dest_extra_alpha_scan) { 771 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); 772 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 773 clip_left + span_left; 774 int col_start = span_left < clip_left ? clip_left - span_left : 0; 775 int col_end = 776 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 777 if (col_end < col_start) 778 return; // do nothing. 779 dest_scan += col_start << 2; 780 #if 1 781 int src_alpha = m_Alpha * cover_scan / 255; 782 for (int col = col_start; col < col_end; col++) { 783 int src_alpha1 = src_alpha * clip_scan[col] / 255; 784 if (!src_alpha1) { 785 dest_scan += 4; 786 continue; 787 } 788 if (src_alpha1 == 255) { 789 *(FX_DWORD*)dest_scan = m_Color; 790 dest_scan += 4; 791 } else { 792 // Dest format: Rgb or Rgb32 793 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); 794 dest_scan++; 795 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); 796 dest_scan++; 797 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); 798 dest_scan += 2; 799 } 800 } 801 #else 802 if (m_bFullCover) { 803 for (int col = col_start; col < col_end; col++) { 804 int src_alpha = m_Alpha * clip_scan[col] / 255; 805 if (!src_alpha) { 806 dest_scan += 4; 807 continue; 808 } 809 if (src_alpha == 255) { 810 *(FX_DWORD*)dest_scan = m_Color; 811 dest_scan += 4; 812 } else { 813 // Dest format: Rgb or Rgb32 814 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); 815 dest_scan++; 816 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); 817 dest_scan++; 818 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); 819 dest_scan += 2; 820 } 821 } 822 } else { 823 // Rgb32 824 int src_alpha = m_Alpha * cover_scan / 255; 825 for (int col = col_start; col < col_end; col++) { 826 int src_alpha1 = src_alpha * clip_scan[col] / 255; 827 if (!src_alpha1) { 828 dest_scan += 4; 829 continue; 830 } 831 if (src_alpha1 == 255) { 832 *(FX_DWORD*)dest_scan = m_Color; 833 dest_scan += 4; 834 } else { 835 // Dest format: Rgb or Rgb32 836 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); 837 dest_scan++; 838 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); 839 dest_scan++; 840 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); 841 dest_scan += 2; 842 } 843 } 844 } 845 #endif 846 } 847 void CFX_SkiaRenderer::CompositeSpanRGB32_7(uint8_t* dest_scan, 848 uint8_t* ori_scan, 849 int Bpp, 850 int span_left, 851 int span_len, 852 int span_top, 853 uint8_t cover_scan, 854 int clip_top, 855 int clip_left, 856 int clip_right, 857 uint8_t* clip_scan, 858 uint8_t* dest_extra_alpha_scan) { 859 ASSERT(!m_pDevice->IsCmykImage()); 860 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); 861 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left << 2); 862 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 863 clip_left + span_left; 864 int col_start = span_left < clip_left ? clip_left - span_left : 0; 865 int col_end = 866 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 867 if (col_end < col_start) 868 return; // do nothing. 869 dest_scan += col_start << 2; 870 ori_scan += col_start << 2; 871 #if 1 872 for (int col = col_start; col < col_end; col++) { 873 int src_alpha = m_Alpha * clip_scan[col] / 255; 874 if (src_alpha == 255 && cover_scan == 255) { 875 *(FX_DWORD*)dest_scan = m_Color; 876 dest_scan += 4; 877 ori_scan += 4; 878 continue; 879 } 880 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); 881 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); 882 int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); 883 ori_scan += 2; 884 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); 885 dest_scan++; 886 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); 887 dest_scan++; 888 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); 889 dest_scan += 2; 890 } 891 #else 892 if (m_bFullCover) { 893 for (int col = col_start; col < col_end; col++) { 894 int src_alpha = m_Alpha * clip_scan[col] / 255; 895 if (!src_alpha) { 896 *(FX_DWORD*)dest_scan = *(FX_DWORD*)ori_scan; 897 dest_scan += 4; 898 ori_scan += 4; 899 continue; 900 } 901 if (src_alpha == 255) { 902 *(FX_DWORD*)dest_scan = m_Color; 903 dest_scan += 4; 904 ori_scan += 4; 905 continue; 906 } 907 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); 908 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); 909 *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); 910 dest_scan += 2; 911 ori_scan += 2; 912 } 913 } else { 914 for (int col = col_start; col < col_end; col++) { 915 int src_alpha = m_Alpha * clip_scan[col] / 255; 916 if (src_alpha == 255 && cover_scan == 255) { 917 *(FX_DWORD*)dest_scan = m_Color; 918 dest_scan += 4; 919 ori_scan += 4; 920 continue; 921 } 922 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); 923 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); 924 int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); 925 ori_scan += 2; 926 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); 927 dest_scan++; 928 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); 929 dest_scan++; 930 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); 931 dest_scan += 2; 932 } 933 } 934 #endif 935 } 936 /*-----------------------------------------------------------------------------------------------------*/ 937 void CFX_SkiaRenderer::CompositeSpanRGB24_2(uint8_t* dest_scan, 938 uint8_t* ori_scan, 939 int Bpp, 940 int span_left, 941 int span_len, 942 int span_top, 943 uint8_t cover_scan, 944 int clip_top, 945 int clip_left, 946 int clip_right, 947 uint8_t* clip_scan, 948 uint8_t* dest_extra_alpha_scan) { 949 dest_scan = 950 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); 951 int col_start = span_left < clip_left ? clip_left - span_left : 0; 952 int col_end = 953 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 954 if (col_end < col_start) 955 return; // do nothing. 956 dest_scan += (col_start << 1) + col_start; 957 int src_alpha; 958 #if 0 959 if (m_bFullCover) 960 src_alpha = m_Alpha; 961 else 962 #endif 963 src_alpha = m_Alpha * cover_scan / 255; 964 if (src_alpha == 255) { 965 for (int col = col_start; col < col_end; col++) { 966 *dest_scan++ = m_Blue; 967 *dest_scan++ = m_Green; 968 *dest_scan++ = m_Red; 969 } 970 return; 971 } 972 for (int col = col_start; col < col_end; col++) { 973 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); 974 dest_scan++; 975 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); 976 dest_scan++; 977 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); 978 dest_scan++; 979 } 980 } 981 void CFX_SkiaRenderer::CompositeSpanRGB24_3(uint8_t* dest_scan, 982 uint8_t* ori_scan, 983 int Bpp, 984 int span_left, 985 int span_len, 986 int span_top, 987 uint8_t cover_scan, 988 int clip_top, 989 int clip_left, 990 int clip_right, 991 uint8_t* clip_scan, 992 uint8_t* dest_extra_alpha_scan) { 993 ASSERT(!m_pDevice->IsCmykImage()); 994 dest_scan = 995 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); 996 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left + 997 (span_left << 1); 998 int col_start = span_left < clip_left ? clip_left - span_left : 0; 999 int col_end = 1000 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 1001 if (col_end < col_start) 1002 return; // do nothing. 1003 dest_scan += (col_start << 1) + col_start; 1004 ori_scan += (col_start << 1) + col_start; 1005 if (m_Alpha == 255 && cover_scan == 255) { 1006 for (int col = col_start; col < col_end; col++) { 1007 *dest_scan++ = m_Blue; 1008 *dest_scan++ = m_Green; 1009 *dest_scan++ = m_Red; 1010 } 1011 return; 1012 } 1013 for (int col = col_start; col < col_end; col++) { 1014 #if 0 1015 if (m_bFullCover) { 1016 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, m_Alpha); 1017 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, m_Alpha); 1018 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, m_Alpha); 1019 continue; 1020 } 1021 #endif 1022 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, m_Alpha); 1023 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, m_Alpha); 1024 int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, m_Alpha); 1025 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); 1026 dest_scan++; 1027 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); 1028 dest_scan++; 1029 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); 1030 dest_scan++; 1031 } 1032 } 1033 void CFX_SkiaRenderer::CompositeSpanRGB24_6(uint8_t* dest_scan, 1034 uint8_t* ori_scan, 1035 int Bpp, 1036 int span_left, 1037 int span_len, 1038 int span_top, 1039 uint8_t cover_scan, 1040 int clip_top, 1041 int clip_left, 1042 int clip_right, 1043 uint8_t* clip_scan, 1044 uint8_t* dest_extra_alpha_scan) { 1045 dest_scan = 1046 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); 1047 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 1048 clip_left + span_left; 1049 int col_start = span_left < clip_left ? clip_left - span_left : 0; 1050 int col_end = 1051 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 1052 if (col_end < col_start) 1053 return; // do nothing. 1054 dest_scan += col_start + (col_start << 1); 1055 #if 1 1056 int src_alpha = m_Alpha * cover_scan / 255; 1057 for (int col = col_start; col < col_end; col++) { 1058 int src_alpha1 = src_alpha * clip_scan[col] / 255; 1059 if (!src_alpha1) { 1060 dest_scan += 3; 1061 continue; 1062 } 1063 if (src_alpha1 == 255) { 1064 *dest_scan++ = m_Blue; 1065 *dest_scan++ = m_Green; 1066 *dest_scan++ = m_Red; 1067 } else { 1068 // Dest format: Rgb 1069 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); 1070 dest_scan++; 1071 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); 1072 dest_scan++; 1073 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); 1074 dest_scan++; 1075 } 1076 } 1077 #else 1078 if (m_bFullCover) { 1079 for (int col = col_start; col < col_end; col++) { 1080 int src_alpha = m_Alpha * clip_scan[col] / 255; 1081 if (!src_alpha) { 1082 dest_scan += 3; 1083 continue; 1084 } 1085 if (src_alpha == 255) { 1086 *dest_scan++ = m_Blue; 1087 *dest_scan++ = m_Green; 1088 *dest_scan++ = m_Red; 1089 } else { 1090 // Dest format: Rgb 1091 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); 1092 dest_scan++; 1093 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); 1094 dest_scan++; 1095 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); 1096 dest_scan++; 1097 } 1098 } 1099 } else { 1100 int src_alpha = m_Alpha * cover_scan / 255; 1101 for (int col = col_start; col < col_end; col++) { 1102 int src_alpha1 = src_alpha * clip_scan[col] / 255; 1103 if (!src_alpha1) { 1104 dest_scan += 3; 1105 continue; 1106 } 1107 if (src_alpha1 == 255) { 1108 *dest_scan++ = m_Blue; 1109 *dest_scan++ = m_Green; 1110 *dest_scan++ = m_Red; 1111 } else { 1112 // Dest format: Rgb 1113 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); 1114 dest_scan++; 1115 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); 1116 dest_scan++; 1117 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); 1118 dest_scan++; 1119 } 1120 } 1121 } 1122 #endif 1123 } 1124 void CFX_SkiaRenderer::CompositeSpanRGB24_7(uint8_t* dest_scan, 1125 uint8_t* ori_scan, 1126 int Bpp, 1127 int span_left, 1128 int span_len, 1129 int span_top, 1130 uint8_t cover_scan, 1131 int clip_top, 1132 int clip_left, 1133 int clip_right, 1134 uint8_t* clip_scan, 1135 uint8_t* dest_extra_alpha_scan) { 1136 ASSERT(!m_pDevice->IsCmykImage()); 1137 dest_scan = 1138 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); 1139 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left + 1140 (span_left << 1); 1141 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 1142 clip_left + span_left; 1143 int col_start = span_left < clip_left ? clip_left - span_left : 0; 1144 int col_end = 1145 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 1146 if (col_end < col_start) 1147 return; // do nothing. 1148 dest_scan += col_start + (col_start << 1); 1149 ori_scan += col_start + (col_start << 1); 1150 #if 1 1151 for (int col = col_start; col < col_end; col++) { 1152 int src_alpha = m_Alpha * clip_scan[col] / 255; 1153 if (src_alpha == 255 && cover_scan == 255) { 1154 *dest_scan++ = m_Blue; 1155 *dest_scan++ = m_Green; 1156 *dest_scan++ = m_Red; 1157 ori_scan += 3; 1158 continue; 1159 } 1160 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); 1161 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); 1162 int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); 1163 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); 1164 dest_scan++; 1165 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); 1166 dest_scan++; 1167 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); 1168 dest_scan++; 1169 } 1170 #else 1171 if (m_bFullCover) { 1172 for (int col = col_start; col < col_end; col++) { 1173 int src_alpha = m_Alpha * clip_scan[col] / 255; 1174 if (!src_alpha) { 1175 *dest_scan++ = *ori_scan++; 1176 *dest_scan++ = *ori_scan++; 1177 *dest_scan++ = *ori_scan++; 1178 continue; 1179 } 1180 if (src_alpha == 255) { 1181 *dest_scan++ = m_Blue; 1182 *dest_scan++ = m_Green; 1183 *dest_scan++ = m_Red; 1184 ori_scan += 3; 1185 continue; 1186 } 1187 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); 1188 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); 1189 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); 1190 } 1191 } else { 1192 for (int col = col_start; col < col_end; col++) { 1193 int src_alpha = m_Alpha * clip_scan[col] / 255; 1194 if (src_alpha == 255 && cover_scan == 255) { 1195 *dest_scan++ = m_Blue; 1196 *dest_scan++ = m_Green; 1197 *dest_scan++ = m_Red; 1198 ori_scan += 3; 1199 continue; 1200 } 1201 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); 1202 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); 1203 int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); 1204 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); 1205 dest_scan++; 1206 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); 1207 dest_scan++; 1208 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); 1209 dest_scan++; 1210 } 1211 } 1212 #endif 1213 } 1214 void CFX_SkiaRenderer::CompositeSpanRGB24_10(uint8_t* dest_scan, 1215 uint8_t* ori_scan, 1216 int Bpp, 1217 int span_left, 1218 int span_len, 1219 int span_top, 1220 uint8_t cover_scan, 1221 int clip_top, 1222 int clip_left, 1223 int clip_right, 1224 uint8_t* clip_scan, 1225 uint8_t* dest_extra_alpha_scan) { 1226 dest_scan = 1227 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); 1228 dest_extra_alpha_scan = 1229 (uint8_t*)m_pDevice->m_pAlphaMask->GetScanline(span_top) + span_left; 1230 int col_start = span_left < clip_left ? clip_left - span_left : 0; 1231 int col_end = 1232 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 1233 if (col_end < col_start) 1234 return; // do nothing. 1235 dest_scan += col_start + (col_start << 1); 1236 #if 1 1237 if (m_Alpha == 255 && cover_scan == 255) { 1238 for (int col = col_start; col < col_end; col++) { 1239 *dest_scan++ = (uint8_t)m_Blue; 1240 *dest_scan++ = (uint8_t)m_Green; 1241 *dest_scan++ = (uint8_t)m_Red; 1242 *dest_extra_alpha_scan++ = 255; 1243 } 1244 return; 1245 } 1246 int src_alpha = m_Alpha * cover_scan / 255; 1247 for (int col = col_start; col < col_end; col++) { 1248 // Dest format: Rgba 1249 // calculate destination alpha (it's union of source and dest alpha) 1250 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - 1251 (*dest_extra_alpha_scan) * src_alpha / 255; 1252 *dest_extra_alpha_scan++ = dest_alpha; 1253 int alpha_ratio = src_alpha * 255 / dest_alpha; 1254 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 1255 dest_scan++; 1256 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 1257 dest_scan++; 1258 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 1259 dest_scan++; 1260 } 1261 #else 1262 if (m_bFullCover) { 1263 if (m_Alpha == 255) { 1264 for (int col = col_start; col < col_end; col++) { 1265 *dest_scan++ = (uint8_t)m_Blue; 1266 *dest_scan++ = (uint8_t)m_Green; 1267 *dest_scan++ = (uint8_t)m_Red; 1268 *dest_extra_alpha_scan++ = 255; 1269 } 1270 return; 1271 } 1272 for (int col = col_start; col < col_end; col++) { 1273 // Dest format: Rgba 1274 // calculate destination alpha (it's union of source and dest alpha) 1275 uint8_t dest_alpha = (*dest_extra_alpha_scan) + m_Alpha - 1276 (*dest_extra_alpha_scan) * m_Alpha / 255; 1277 *dest_extra_alpha_scan++ = dest_alpha; 1278 int alpha_ratio = m_Alpha * 255 / dest_alpha; 1279 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 1280 dest_scan++; 1281 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 1282 dest_scan++; 1283 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 1284 dest_scan++; 1285 } 1286 } else { 1287 if (m_Alpha == 255 && cover_scan == 255) { 1288 for (int col = col_start; col < col_end; col++) { 1289 *dest_scan++ = (uint8_t)m_Blue; 1290 *dest_scan++ = (uint8_t)m_Green; 1291 *dest_scan++ = (uint8_t)m_Red; 1292 *dest_extra_alpha_scan++ = 255; 1293 } 1294 return; 1295 } 1296 int src_alpha = m_Alpha * cover_scan / 255; 1297 for (int col = col_start; col < col_end; col++) { 1298 // Dest format: Rgba 1299 // calculate destination alpha (it's union of source and dest alpha) 1300 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - 1301 (*dest_extra_alpha_scan) * src_alpha / 255; 1302 *dest_extra_alpha_scan++ = dest_alpha; 1303 int alpha_ratio = src_alpha * 255 / dest_alpha; 1304 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 1305 dest_scan++; 1306 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 1307 dest_scan++; 1308 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 1309 dest_scan++; 1310 } 1311 } 1312 #endif 1313 } 1314 void CFX_SkiaRenderer::CompositeSpanRGB24_14(uint8_t* dest_scan, 1315 uint8_t* ori_scan, 1316 int Bpp, 1317 int span_left, 1318 int span_len, 1319 int span_top, 1320 uint8_t cover_scan, 1321 int clip_top, 1322 int clip_left, 1323 int clip_right, 1324 uint8_t* clip_scan, 1325 uint8_t* dest_extra_alpha_scan) { 1326 dest_scan = 1327 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); 1328 dest_extra_alpha_scan = 1329 (uint8_t*)m_pDevice->m_pAlphaMask->GetScanline(span_top) + span_left; 1330 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - 1331 clip_left + span_left; 1332 int col_start = span_left < clip_left ? clip_left - span_left : 0; 1333 int col_end = 1334 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 1335 if (col_end < col_start) 1336 return; // do nothing. 1337 dest_scan += col_start + (col_start << 1); 1338 #if 1 1339 int src_alpha = m_Alpha * cover_scan / 255; 1340 for (int col = col_start; col < col_end; col++) { 1341 int src_alpha1 = src_alpha * clip_scan[col] / 255; 1342 if (!src_alpha1) { 1343 dest_extra_alpha_scan++; 1344 dest_scan += 3; 1345 continue; 1346 } 1347 if (src_alpha1 == 255) { 1348 *dest_scan++ = (uint8_t)m_Blue; 1349 *dest_scan++ = (uint8_t)m_Green; 1350 *dest_scan++ = (uint8_t)m_Red; 1351 *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; 1352 } else { 1353 // Dest format: Rgba 1354 // calculate destination alpha (it's union of source and dest alpha) 1355 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha1 - 1356 (*dest_extra_alpha_scan) * src_alpha1 / 255; 1357 *dest_extra_alpha_scan++ = dest_alpha; 1358 int alpha_ratio = src_alpha1 * 255 / dest_alpha; 1359 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 1360 dest_scan++; 1361 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 1362 dest_scan++; 1363 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 1364 dest_scan++; 1365 } 1366 } 1367 #else 1368 if (m_bFullCover) { 1369 for (int col = col_start; col < col_end; col++) { 1370 int src_alpha = m_Alpha * clip_scan[col] / 255; 1371 if (!src_alpha) { 1372 dest_extra_alpha_scan++; 1373 dest_scan += 3; 1374 continue; 1375 } 1376 if (src_alpha == 255) { 1377 *dest_scan++ = (uint8_t)m_Blue; 1378 *dest_scan++ = (uint8_t)m_Green; 1379 *dest_scan++ = (uint8_t)m_Red; 1380 *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; 1381 } else { 1382 // Dest format: Rgba 1383 // calculate destination alpha (it's union of source and dest alpha) 1384 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - 1385 (*dest_extra_alpha_scan) * src_alpha / 255; 1386 *dest_extra_alpha_scan++ = dest_alpha; 1387 int alpha_ratio = src_alpha * 255 / dest_alpha; 1388 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 1389 dest_scan++; 1390 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 1391 dest_scan++; 1392 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 1393 dest_scan++; 1394 } 1395 } 1396 } else { 1397 int src_alpha = m_Alpha * cover_scan / 255; 1398 for (int col = col_start; col < col_end; col++) { 1399 int src_alpha1 = m_Alpha * cover_scan * clip_scan[col] / 255; 1400 if (!src_alpha1) { 1401 dest_extra_alpha_scan++; 1402 dest_scan += 3; 1403 continue; 1404 } 1405 if (src_alpha1 == 255) { 1406 *dest_scan++ = (uint8_t)m_Blue; 1407 *dest_scan++ = (uint8_t)m_Green; 1408 *dest_scan++ = (uint8_t)m_Red; 1409 *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; 1410 } else { 1411 // Dest format: Rgba 1412 // calculate destination alpha (it's union of source and dest alpha) 1413 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha1 - 1414 (*dest_extra_alpha_scan) * src_alpha1 / 255; 1415 *dest_extra_alpha_scan++ = dest_alpha; 1416 int alpha_ratio = src_alpha1 * 255 / dest_alpha; 1417 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 1418 dest_scan++; 1419 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 1420 dest_scan++; 1421 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 1422 dest_scan++; 1423 } 1424 } 1425 } 1426 #endif 1427 } 1428 /*-----------------------------------------------------------------------------------------------------*/ 1429 1430 // A general alpha merge function (with clipping mask). Cmyka/Cmyk device. 1431 void CFX_SkiaRenderer::CompositeSpanCMYK(uint8_t* dest_scan, 1432 uint8_t* ori_scan, 1433 int Bpp, 1434 int span_left, 1435 int span_len, 1436 int span_top, 1437 uint8_t cover_scan, 1438 int clip_top, 1439 int clip_left, 1440 int clip_right, 1441 uint8_t* clip_scan, 1442 uint8_t* dest_extra_alpha_scan) { 1443 ASSERT(!m_bRgbByteOrder); 1444 // Cmyk(a) 1445 int col_start = span_left < clip_left ? clip_left - span_left : 0; 1446 int col_end = 1447 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); 1448 if (col_end < col_start) 1449 return; // do nothing. 1450 dest_scan += col_start * 4; 1451 Bpp; // for avoid compile warning. 1452 1453 if (dest_extra_alpha_scan) { 1454 // CMYKa 1455 for (int col = col_start; col < col_end; col++) { 1456 int src_alpha; 1457 if (m_bFullCover) { 1458 if (clip_scan) 1459 src_alpha = m_Alpha * clip_scan[col] / 255; 1460 else 1461 src_alpha = m_Alpha; 1462 } else { 1463 if (clip_scan) 1464 src_alpha = m_Alpha * cover_scan * clip_scan[col] / 255 / 255; 1465 else 1466 src_alpha = m_Alpha * cover_scan / 255; 1467 } 1468 1469 if (src_alpha) { 1470 if (src_alpha == 255) { 1471 *(FX_CMYK*)dest_scan = m_Color; 1472 *dest_extra_alpha_scan = (uint8_t)m_Alpha; 1473 } else { 1474 // Dest format: Cmyka 1475 // calculate destination alpha (it's union of source and dest alpha) 1476 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - 1477 (*dest_extra_alpha_scan) * src_alpha / 255; 1478 *dest_extra_alpha_scan++ = dest_alpha; 1479 int alpha_ratio = src_alpha * 255 / dest_alpha; 1480 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); 1481 dest_scan++; 1482 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); 1483 dest_scan++; 1484 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); 1485 dest_scan++; 1486 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); 1487 dest_scan++; 1488 continue; 1489 } 1490 } 1491 dest_extra_alpha_scan++; 1492 dest_scan += 4; 1493 } 1494 } else { 1495 // CMYK 1496 for (int col = col_start; col < col_end; col++) { 1497 int src_alpha; 1498 if (clip_scan) 1499 src_alpha = m_Alpha * cover_scan * clip_scan[col] / 255 / 255; 1500 else 1501 src_alpha = m_Alpha * cover_scan / 255; 1502 1503 if (src_alpha) { 1504 if (src_alpha == 255) { 1505 *(FX_CMYK*)dest_scan = m_Color; 1506 } else { 1507 // Dest format: cmyk 1508 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); 1509 dest_scan++; 1510 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); 1511 dest_scan++; 1512 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); 1513 dest_scan++; 1514 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); 1515 dest_scan++; 1516 continue; 1517 } 1518 } 1519 dest_scan += 4; 1520 } 1521 } 1522 } 1523 1524 //-------------------------------------------------------------------- 1525 FX_BOOL CFX_SkiaRenderer::Init( 1526 CFX_DIBitmap* pDevice, 1527 CFX_DIBitmap* pOriDevice, 1528 const CFX_ClipRgn* pClipRgn, 1529 FX_DWORD color, 1530 FX_BOOL bFullCover, 1531 FX_BOOL bRgbByteOrder, 1532 int alpha_flag, 1533 void* pIccTransform) // The alpha flag must be fill_flag if exist. 1534 { 1535 m_pDevice = pDevice; 1536 m_pClipRgn = pClipRgn; 1537 m_bRgbByteOrder = bRgbByteOrder; 1538 m_pOriDevice = pOriDevice; 1539 m_pDestScan = NULL; 1540 m_pDestExtraAlphaScan = NULL; 1541 m_pOriScan = NULL; 1542 m_pClipScan = NULL; 1543 composite_span = NULL; 1544 if (m_pClipRgn) 1545 m_ClipBox = m_pClipRgn->GetBox(); 1546 else { 1547 m_ClipBox.left = m_ClipBox.top = 0; 1548 m_ClipBox.right = m_pDevice->GetWidth(); 1549 m_ClipBox.bottom = m_pDevice->GetHeight(); 1550 } 1551 m_pClipMask = NULL; 1552 if (m_pClipRgn && m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { 1553 m_pClipMask = m_pClipRgn->GetMask(); 1554 m_pClipScan = m_pClipMask->GetBuffer(); 1555 } 1556 if (m_pDevice->m_pAlphaMask) 1557 m_pDestExtraAlphaScan = m_pDevice->m_pAlphaMask->GetBuffer(); 1558 if (m_pOriDevice) 1559 m_pOriScan = m_pOriDevice->GetBuffer(); 1560 m_pDestScan = m_pDevice->GetBuffer(); 1561 1562 m_bFullCover = bFullCover; 1563 1564 FX_BOOL bObjectCMYK = FXGETFLAG_COLORTYPE(alpha_flag); 1565 FX_BOOL bDeviceCMYK = pDevice->IsCmykImage(); 1566 1567 m_Alpha = bObjectCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); 1568 1569 ICodec_IccModule* pIccModule = NULL; 1570 // No lcms engine, we skip the transform 1571 if (!CFX_GEModule::Get()->GetCodecModule() || 1572 !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) 1573 pIccTransform = NULL; 1574 else 1575 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); 1576 1577 if (m_pDevice->GetBPP() == 8) { // Gray(a) device 1578 ASSERT(!m_bRgbByteOrder); 1579 if (m_pDevice->IsAlphaMask()) { 1580 // Alpha Mask 1581 m_Gray = 255; 1582 } else { 1583 // Gray(a) device 1584 if (pIccTransform) { 1585 uint8_t gray; 1586 color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); 1587 pIccModule->TranslateScanline(pIccTransform, &gray, 1588 (const uint8_t*)&color, 1); 1589 m_Gray = gray; 1590 } else { 1591 if (bObjectCMYK) { 1592 uint8_t r, g, b; 1593 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), 1594 FXSYS_GetYValue(color), FXSYS_GetKValue(color), r, 1595 g, b); 1596 m_Gray = FXRGB2GRAY(r, g, b); 1597 } else { 1598 m_Gray = 1599 FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); 1600 } 1601 } 1602 } 1603 } else { 1604 if (bDeviceCMYK) { // Cmyk(a) Device 1605 ASSERT(!m_bRgbByteOrder); 1606 // TODO... opt for cmyk 1607 composite_span = &CFX_SkiaRenderer::CompositeSpanCMYK; 1608 if (bObjectCMYK) { 1609 m_Color = FXCMYK_TODIB(color); 1610 if (pIccTransform) 1611 pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, 1612 (const uint8_t*)&m_Color, 1); 1613 } else { // Object RGB 1614 if (!pIccTransform) 1615 return FALSE; 1616 color = FXARGB_TODIB(color); 1617 pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, 1618 (const uint8_t*)&color, 1); 1619 } 1620 m_Red = ((uint8_t*)&m_Color)[0]; 1621 m_Green = ((uint8_t*)&m_Color)[1]; 1622 m_Blue = ((uint8_t*)&m_Color)[2]; 1623 m_Gray = ((uint8_t*)&m_Color)[3]; 1624 return TRUE; 1625 } 1626 if (pIccTransform) { 1627 color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); 1628 pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, 1629 (const uint8_t*)&color, 1); 1630 ((uint8_t*)&m_Color)[3] = m_Alpha; 1631 m_Red = ((uint8_t*)&m_Color)[2]; 1632 m_Green = ((uint8_t*)&m_Color)[1]; 1633 m_Blue = ((uint8_t*)&m_Color)[0]; 1634 // Need Johnson to improvement it. 1635 if (m_bRgbByteOrder) { 1636 // swap 1637 m_Red = ((uint8_t*)&m_Color)[0]; 1638 m_Blue = ((uint8_t*)&m_Color)[2]; 1639 m_Color = FXARGB_TODIB(m_Color); 1640 m_Color = FXARGB_TOBGRORDERDIB(m_Color); 1641 } 1642 } else { 1643 if (bObjectCMYK) { 1644 uint8_t r, g, b; 1645 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), 1646 FXSYS_GetYValue(color), FXSYS_GetKValue(color), r, g, 1647 b); 1648 m_Color = FXARGB_MAKE(m_Alpha, r, g, b); 1649 if (m_bRgbByteOrder) { 1650 m_Color = FXARGB_TOBGRORDERDIB(m_Color); 1651 m_Red = b; 1652 m_Green = g; 1653 m_Blue = r; // 1654 } else { 1655 m_Color = FXARGB_TODIB(m_Color); 1656 m_Red = r; 1657 m_Green = g; 1658 m_Blue = b; // 1659 } 1660 } else { 1661 if (m_bRgbByteOrder) { 1662 m_Color = FXARGB_TOBGRORDERDIB(color); 1663 ArgbDecode(color, m_Alpha, m_Blue, m_Green, m_Red); // 1664 } else { 1665 m_Color = FXARGB_TODIB(color); 1666 ArgbDecode(color, m_Alpha, m_Red, m_Green, m_Blue); 1667 } 1668 } 1669 } 1670 } 1671 // Get palette transparency selector 1672 m_ProcessFilter = 1673 (m_pOriDevice ? 1 : 0) /* has Ori Device flag */ 1674 + (m_pDevice->GetBPP() >= 8 ? 2 : 0) /* bpp flag */ 1675 + (m_pClipMask ? 4 : 0) /* has clip region flag */ 1676 + (m_pDevice->m_pAlphaMask ? 8 : 0); /* has Alpha Mask chanel flag */ 1677 switch (m_ProcessFilter) { 1678 case 0: 1679 composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_0; 1680 break; 1681 case 2: { 1682 if (m_pDevice->GetBPP() == 8) 1683 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_2; 1684 else if (m_pDevice->GetBPP() == 24) 1685 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_2; 1686 else 1687 composite_span = m_pDevice->HasAlpha() 1688 ? &CFX_SkiaRenderer::CompositeSpanARGB_2 1689 : &CFX_SkiaRenderer::CompositeSpanRGB32_2; 1690 } break; 1691 case 3: { 1692 if (m_pDevice->GetBPP() == 8) 1693 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_3; 1694 else if (m_pDevice->GetBPP() == 24) 1695 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_3; 1696 else 1697 composite_span = m_pDevice->HasAlpha() 1698 ? &CFX_SkiaRenderer::CompositeSpanARGB_3 1699 : &CFX_SkiaRenderer::CompositeSpanRGB32_3; 1700 } break; 1701 case 4: 1702 composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_4; 1703 break; 1704 case 6: { 1705 if (m_pDevice->GetBPP() == 8) 1706 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_6; 1707 else if (m_pDevice->GetBPP() == 24) 1708 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_6; 1709 else 1710 composite_span = m_pDevice->HasAlpha() 1711 ? &CFX_SkiaRenderer::CompositeSpanARGB_6 1712 : &CFX_SkiaRenderer::CompositeSpanRGB32_6; 1713 } break; 1714 case 7: { 1715 if (m_pDevice->GetBPP() == 8) 1716 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_7; 1717 else if (m_pDevice->GetBPP() == 24) 1718 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_7; 1719 else 1720 composite_span = m_pDevice->HasAlpha() 1721 ? &CFX_SkiaRenderer::CompositeSpanARGB_7 1722 : &CFX_SkiaRenderer::CompositeSpanRGB32_7; 1723 } break; 1724 case 1: 1725 case 5: 1726 case 8: 1727 case 9: 1728 case 11: 1729 case 12: 1730 case 13: 1731 case 15: 1732 // TODO... 1733 break; 1734 case 10: 1735 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_10; 1736 break; 1737 case 14: 1738 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_14; 1739 break; 1740 } 1741 return !!composite_span; 1742 } 1743 1744 /*----------------------------------------------------------------------------------------------------*/ 1745 void CFX_SkiaA8Renderer::blitAntiH(int x, 1746 int y, 1747 const SkAlpha antialias[], 1748 const int16_t runs[]) { 1749 FXSYS_assert(m_pDevice); 1750 int dst_y = y - m_Top; 1751 if (dst_y < 0 || dst_y >= m_pDevice->GetHeight()) 1752 return; 1753 1754 uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y; 1755 uint8_t* dest_pos = dest_scan; 1756 while (1) { 1757 if (x >= m_dstWidth) 1758 return; 1759 int width = runs[0]; 1760 SkASSERT(width >= 0); 1761 if (width <= 0) 1762 return; 1763 unsigned aa = antialias[0]; 1764 if (aa) { 1765 int col_start = x < m_Left ? 0 : x - m_Left; 1766 int col_end = x + width; 1767 col_end = col_end < m_dstWidth ? col_end - m_Left : m_pDevice->GetWidth(); 1768 int result = col_end - col_start; 1769 if (result > 0) { 1770 dest_pos = dest_scan + col_start; 1771 if (result >= 4) 1772 FXSYS_memset(dest_pos, FXARGB_MAKE(aa, aa, aa, aa), result); 1773 else 1774 FXSYS_memset(dest_pos, aa, result); 1775 } 1776 } 1777 runs += width; 1778 antialias += width; 1779 x += width; 1780 } 1781 } 1782 void CFX_SkiaA8Renderer::blitH(int x, int y, int width) { 1783 FXSYS_assert(m_pDevice); 1784 int dst_y = y - m_Top; 1785 if (dst_y < 0 || dst_y >= m_pDevice->GetHeight()) 1786 return; 1787 if (x >= m_dstWidth) 1788 return; 1789 uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y; 1790 int col_start = x < m_Left ? 0 : x - m_Left; 1791 int col_end = x + width; 1792 col_end = col_end < m_dstWidth ? col_end - m_Left : m_pDevice->GetWidth(); 1793 int result = col_end - col_start; 1794 if (result > 0) { 1795 uint8_t* dest_pos = dest_scan + col_start; 1796 if (result >= 4) 1797 FXSYS_memset(dest_pos, 0xffffffff, result); 1798 else 1799 FXSYS_memset(dest_pos, 255, result); 1800 } 1801 } 1802 void CFX_SkiaA8Renderer::blitV(int x, int y, int height, SkAlpha alpha) { 1803 FXSYS_assert(alpha); 1804 if (alpha == 255) { 1805 blitRect(x, y, 1, height); 1806 } else { 1807 int16_t runs[2]; 1808 runs[0] = 1; 1809 runs[1] = 0; 1810 while (--height >= 0) { 1811 if (y >= m_dstHeight) 1812 return; 1813 blitAntiH(x, y++, &alpha, runs); 1814 } 1815 } 1816 } 1817 void CFX_SkiaA8Renderer::blitRect(int x, int y, int width, int height) { 1818 FXSYS_assert(m_pDevice); 1819 while (--height >= 0) { 1820 if (y >= m_dstHeight) 1821 return; 1822 blitH(x, y++, width); 1823 } 1824 } 1825 1826 void CFX_SkiaA8Renderer::blitAntiRect(int x, 1827 int y, 1828 int width, 1829 int height, 1830 SkAlpha leftAlpha, 1831 SkAlpha rightAlpha) { 1832 blitV(x++, y, height, leftAlpha); 1833 if (width > 0) { 1834 blitRect(x, y, width, height); 1835 x += width; 1836 } 1837 blitV(x, y, height, rightAlpha); 1838 } 1839 1840 FX_BOOL CFX_SkiaA8Renderer::Init(CFX_DIBitmap* pDevice, int Left, int Top) { 1841 m_pDevice = pDevice; 1842 m_Left = Left; 1843 m_Top = Top; 1844 if (pDevice) { 1845 m_dstWidth = m_Left + pDevice->GetWidth(); 1846 m_dstHeight = m_Top + pDevice->GetHeight(); 1847 } 1848 return TRUE; 1849 } 1850 #endif 1851