| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2013 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 { | 314 { |
| 315 if (attribute.isNull()) | 315 if (attribute.isNull()) |
| 316 return; | 316 return; |
| 317 | 317 |
| 318 if (attribute.is8Bit()) | 318 if (attribute.is8Bit()) |
| 319 parseImageCandidatesFromSrcsetAttribute<LChar>(attribute, attribute.char
acters8(), attribute.length(), imageCandidates, document); | 319 parseImageCandidatesFromSrcsetAttribute<LChar>(attribute, attribute.char
acters8(), attribute.length(), imageCandidates, document); |
| 320 else | 320 else |
| 321 parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.char
acters16(), attribute.length(), imageCandidates, document); | 321 parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.char
acters16(), attribute.length(), imageCandidates, document); |
| 322 } | 322 } |
| 323 | 323 |
| 324 static int selectionLogic(Vector<ImageCandidate>& imageCandidates, float deviceS
caleFactor, bool ignoreSrc) |
| 325 { |
| 326 unsigned i = 0; |
| 327 |
| 328 for (; i < imageCandidates.size() - 1; ++i) { |
| 329 unsigned next = i + 1; |
| 330 float nextDensity; |
| 331 float currentDensity; |
| 332 float geometricMean; |
| 333 if (ignoreSrc) { |
| 334 if (imageCandidates[i].srcOrigin()) |
| 335 continue; |
| 336 if (imageCandidates[next].srcOrigin()) { |
| 337 ++next; |
| 338 if (next >= imageCandidates.size()) |
| 339 break; |
| 340 ASSERT(!imageCandidates[next].srcOrigin()); |
| 341 } |
| 342 } |
| 343 |
| 344 nextDensity = imageCandidates[next].density(); |
| 345 if (nextDensity < deviceScaleFactor) |
| 346 continue; |
| 347 |
| 348 currentDensity = imageCandidates[i].density(); |
| 349 geometricMean = sqrt(currentDensity * nextDensity); |
| 350 if (deviceScaleFactor >= geometricMean) |
| 351 return next; |
| 352 break; |
| 353 } |
| 354 return i; |
| 355 } |
| 356 |
| 324 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, float sour
ceSize, Vector<ImageCandidate>& imageCandidates) | 357 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, float sour
ceSize, Vector<ImageCandidate>& imageCandidates) |
| 325 { | 358 { |
| 326 const float defaultDensityValue = 1.0; | 359 const float defaultDensityValue = 1.0; |
| 327 bool ignoreSrc = false; | 360 bool ignoreSrc = false; |
| 328 if (imageCandidates.isEmpty()) | 361 if (imageCandidates.isEmpty()) |
| 329 return ImageCandidate(); | 362 return ImageCandidate(); |
| 330 | 363 |
| 331 // http://picture.responsiveimages.org/#normalize-source-densities | 364 // http://picture.responsiveimages.org/#normalize-source-densities |
| 332 for (Vector<ImageCandidate>::iterator it = imageCandidates.begin(); it != im
ageCandidates.end(); ++it) { | 365 for (Vector<ImageCandidate>::iterator it = imageCandidates.begin(); it != im
ageCandidates.end(); ++it) { |
| 333 if (it->resourceWidth() > 0) { | 366 if (it->resourceWidth() > 0) { |
| 334 it->setDensity((float)it->resourceWidth() / sourceSize); | 367 it->setDensity((float)it->resourceWidth() / sourceSize); |
| 335 ignoreSrc = true; | 368 ignoreSrc = true; |
| 336 } else if (it->density() < 0) { | 369 } else if (it->density() < 0) { |
| 337 it->setDensity(defaultDensityValue); | 370 it->setDensity(defaultDensityValue); |
| 338 } | 371 } |
| 339 } | 372 } |
| 340 | 373 |
| 341 std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByDe
nsity); | 374 std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByDe
nsity); |
| 342 | 375 |
| 343 unsigned i; | 376 unsigned i = selectionLogic(imageCandidates, deviceScaleFactor, ignoreSrc); |
| 344 for (i = 0; i < imageCandidates.size() - 1; ++i) { | 377 ASSERT(i < imageCandidates.size()); |
| 345 if ((imageCandidates[i].density() >= deviceScaleFactor) && (!ignoreSrc |
| !imageCandidates[i].srcOrigin())) | |
| 346 break; | |
| 347 } | |
| 348 | 378 |
| 349 if (imageCandidates[i].srcOrigin() && ignoreSrc) { | |
| 350 ASSERT(i > 0); | |
| 351 --i; | |
| 352 } | |
| 353 float winningDensity = imageCandidates[i].density(); | 379 float winningDensity = imageCandidates[i].density(); |
| 354 | 380 |
| 355 unsigned winner = i; | 381 unsigned winner = i; |
| 356 // 16. If an entry b in candidates has the same associated ... pixel density
as an earlier entry a in candidates, | 382 // 16. If an entry b in candidates has the same associated ... pixel density
as an earlier entry a in candidates, |
| 357 // then remove entry b | 383 // then remove entry b |
| 358 while ((i > 0) && (imageCandidates[--i].density() == winningDensity)) | 384 while ((i > 0) && (imageCandidates[--i].density() == winningDensity)) |
| 359 winner = i; | 385 winner = i; |
| 360 | 386 |
| 361 return imageCandidates[winner]; | 387 return imageCandidates[winner]; |
| 362 } | 388 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 Vector<ImageCandidate> imageCandidates; | 422 Vector<ImageCandidate> imageCandidates; |
| 397 imageCandidates.append(srcsetImageCandidate); | 423 imageCandidates.append(srcsetImageCandidate); |
| 398 | 424 |
| 399 if (!srcAttribute.isEmpty()) | 425 if (!srcAttribute.isEmpty()) |
| 400 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), DescriptorParsingResult(), ImageCandidate::SrcOrigin)); | 426 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), DescriptorParsingResult(), ImageCandidate::SrcOrigin)); |
| 401 | 427 |
| 402 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates
).toString(); | 428 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates
).toString(); |
| 403 } | 429 } |
| 404 | 430 |
| 405 } | 431 } |
| OLD | NEW |