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