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 |